2020-11-11筆記

szmn發表於2020-11-12

排序的穩定性

相同的數字,是否會因為排序的過程,原來的相對位置被打亂
氣泡排序:相鄰交換的時候,相等的不進行交換的話,這個氣泡排序是穩定的,如果演算法寫成等於也交換,那麼就是不穩定的了
選擇排序:找到最小值的位置,然後把最小值和0號位置的數字進行交換,這個相對位置肯定就變了,所以是不穩定的
歸併排序:merge的過程中,分成了左區域和右區域,只要保證左右兩邊相等的時候先拷貝左區的,左區拷貝完了再拷貝右區的,這樣就可以保持穩定了
快排partition:做不到穩定性
堆排:在建立大根堆的時候,做上浮交換的節點是不一定的,這個交換的操作就會導致不穩定性了

排序演算法的選擇

陣列長度很短(小於60)的時候用插入排序飛快,儘管是O(N2)
樣本量大於60的時候,用歸併排序或者快排
此外,當我們做的是基礎型別排序的時候用快排,比如int,而如果是自己定義的物件進行排序(因為即使是同一個類裡面的比較,不同的例項化的物件之間是有區別的,這也是排序裡面穩定性的意義),所以這個時候為了保持穩定性,我們就使用歸併排序

面試問題

把奇數都放左邊偶數都放右邊,額外空間O(1),並保持相對次序不變,能做到嗎?不能,類比快排的partition穩定性難以做到,同理荷蘭國旗也做不到穩定性

比較器

背:重寫compare方法,如果return的是一個複數,則第一個數更小,如果是正數,則第一個數更大,如果=0,則相等
所以我們通常寫成o1-o2,就是升序排列,o2-o1就是降序

不基於比較的排序

桶排序是個大的概念,包括:
計數排序:用一個hashtable(桶的概念)放每個數字出現的詞頻,也就是把每個數字放到它屬於的桶裡面,然後把輸出,沒有compare這個操作的
基數排序:十位排個序,個位排個序,用到的桶沒有計數排序這麼多

給定一個陣列,求如果排序之後相鄰兩數的最大差值,要求時間O(N)

N個數,準備N+1個桶,先遍歷找到最小值和最大值
如果最小值和最大值相等,那麼直接返回0
比如:一共有9個數,準備10個桶,然後把min-max劃範圍,等分地把數字裝到桶裡去
那麼中間必然存在一個空的桶,而最大的差值必然來自兩個不同的非空桶之間的差值
(1)遍歷陣列找到最大值和最小值
(2)三個N+1的陣列,一個boolean,一個max int和一個min int,分別表示第i號桶的資訊描述,表示這個桶裡面的最大值最小值和是否為空
(3)然後寫一個for迴圈,O(N)的,表示當前數要去哪個桶,然後每個桶的情況更細
(4)然後每個桶的最小和下一個桶的最大值相減,更新最大的差

用陣列結構實現大小固定的佇列和棧

設計一個end指向應該填的位置,start指向應該拿取的時候的位置,用一個size來約束行為,如果end沒到size,那麼就往end加入,如果size不等於0,那麼取的時候總是從start取,這樣就實現了poll和pop的下標的解耦
一定要注意這個引入size從而解耦start和end的操作,很重要

最小棧

維持兩個棧data棧和min棧,新的數比棧頂小的時候的時候把它壓入棧頂,比棧頂大的時候就把棧頂再壓入一次,彈出的時候就一起彈出

如何用兩個佇列實現一個棧結構

比如問到怎麼用佇列實現圖的深度優先遍歷的時候,就可以用這個結構先實現棧,然後再實現深度優先遍歷

如何用兩個棧實現一個佇列