小師弟也跑去找工作了,也就碰到了各種各樣的面試題(就是:
如何產生1-100
之間的100個不重複的隨機數),如果這是你是第一次看到這個題目,也許你的想法有很多。
1:首先從原始陣列中隨機選擇乙個數字,然後將該數字從陣列中剔除,再隨記選,再剔除,重複99次,就解決了。
我們知道從陣列中剔除乙個元素的複雜度為o(n),那麼隨機選取n個數字,它的複雜度就是o(n2)了。
2:用hash作為中間過濾層,因為在陣列中,我們採用隨機數的話,也許隨機數在多次隨機中可能會有重複,所以需要用hash來判斷一下,
如果在hash中重複,則繼續產生隨機數,直到不重複為止,當然這個複雜度就不好說了,得要看隨機數隨機不隨機了,好的話,o(n)搞定,
不走運的話無上限~
可以對應到的就是「洗撲克牌」,在演算法中也叫「洗牌原理」,我們知道洗撲克牌的方式就是隨機的交換撲克牌的位置,又叫做"切牌",當你切了
很多次後,我們的撲克牌就可以認為是足夠亂了,複雜度也就變成了o(n),用**實現就是這樣的。
<1> 先有序的生成52張牌,然後有序的放到陣列中。
<2>從1-52中隨機的產生乙個數,然後將當前次數的位置跟隨機數的位置進行交換,重複52次,我們的牌就可以認為足夠亂了。
4:**實現
<1> 首先定義牌的資料結構,定義乙個「花色」和「數字」
1<2>有序的生成52張牌///2
///具體撲克牌
3///
4public
class
card
5
1<3> 然後就是切牌了,剛才也說了思路,就是拿隨機數的位置與當前i的位置進行交換,不過一說到交換就想起了「氣泡排序」,可能被毒害太///2
///開牌
3///
4public
void
newcard()521
22 card[i - 1] = new
card()23;
27}28 }
深了(┬_┬),不知道你感覺到了沒。
1<4> 最後我們看看效果///2
///洗牌
3///
4public
void
shuffle()
519 }
1using
system;
2using
system.collections.generic;
3using
system.linq;
4using
system.text;
5using
system.threading.tasks;67
namespace827
}2829public
class
cardclass
3042
43///
44///
開牌45
///46
public
void
newcard()
4763
64 card[i - 1] = new
card()65;
69}70}
7172
///73
///洗牌
74///
75public
void
shuffle()
7690}91
92///
93///
輸入牌型
其實「洗牌原理」只要說破了是很簡單的,就是你想不到,哈哈。。。然後小師弟也就明白了,
演算法思想 滑動視窗思想
在解leetcode題的時候,遇到了幾個新的演算法思想,這個系列文章就把leetcode中的一些演算法思想做一些整理,包括老生常談的動態規劃,也包括我最新接觸的滑動視窗思想,並查集等,另外,遇到新的題目的時候也會在這裡做一些整理。起源 計算機網路協議 在介紹滑動視窗思想之前,首先介紹這個演算法思想的...
演算法思想 分治演算法
分而治之 大問題能夠拆成相似的小問題,記住這些小問題需要具有相似性。而後將小問題的每個解合成為大問題的解。所以說大問題如何拆,小問題如何合併才是這個演算法最主要的乙個思想。實際上很多演算法如貪心演算法,動態規劃等等都是要求把大問題拆成小問題。而分治演算法的重要一點就是要適用於能夠重新把小問題的解合併...
record 09 ATM 物件思想 綜合練習
author hasee date 2018 1 17 明確在程式執行期間,有哪些物件參與 取款機 分析物件的行為 資料屬性 資料屬性 所有使用者的資訊 行為屬性 登陸校驗 顯示餘額 取款服務 轉賬服務 定義類 class atm user info 0 def init self f open u...