給定乙個無序整型陣列arr,找到陣列中未出現的最小正整數。
舉例:
arr=[-1,2,3,4] 返回 1;
arr=[1,2,3,4,] 返回 5;
需求:時間複雜度為o(n),額外空間複雜度為o(1);
public
static
intmissnum(int arr)
else
if(arr[l]<=l||arr[l]>r||arr[arr[l]-1]==arr[l])else
}return l+1;
}
分析:
首先這個題目不能用排序 排序的最優是o(nlgn) 比o(n)大 所以只能是線性的時間 只能是遍歷一次出結果
變數解釋:l 表示遍歷過的元素中收集到1-r中的最優情況下的值(通俗的講就是遍歷過來收集到的從小到大有序整數,比如 1,2,5,4,5…. 正好遍歷到第二個5的位置的時候l中收集到了2(l=2) 所以初始化是l=0)
r表示最優情況下能收集到的(想收集到的)有序整數的最大值 所有r初始化時為arr.length;
l和r分別表示遍歷過程的左右邊界 相遇時遍歷結束
主要出現在三個else中的三個情況下:
1.當一路順利遍歷下來時 l就一直遍歷下去(所謂的順利遍歷下來就最優的情況12345….這樣有序的排下去,即arr[l]=l+1)
2.三個條件 當遍歷的值小於下標時即上面12545的情況 l沒收集到遍歷相對的有序值 即前面遍歷時出現沒用的值 佔了乙個位置 使最優下降
當遍歷的值大於r值時即比最大的需要的整數都大 也沒用 我們只要收集到r就已經是最優了 比r大就超出了範圍 佔了乙個位置 使最優下降
當前乙個數和第二個數重複時 也是乙個廢值 佔了乙個位置 使最優下降
出現上面三種情況r– 就是說最優下降 我們收集不到r 的情況 所有最優值在縮小
然後當arr[l]位置上的值為廢值的時候把最後乙個值拿過來賦給他做這個else的判斷 看最後乙個本來因為最優情況縮小無奈被拋棄的值是否符合我們收集的條件 如果符合也可以是l++
3.不符合2中的三個條件就說明出現在了l+1到r之間的值 但是有不是順序出現的值 如arr[3]位置上出現7(本來應該是4)那就把這個值放到他應該在的位置 (即arr[6]的位置上去) 然後把那個位置上的值拿過來判斷上面的三個else 同樣如果符合條件就l++
l不斷增大 r不斷減小 當相遇的時候 結束 輸出l+1
左神演算法 RandomPool
題目 設計一種結構,在該結構中有如下三個功能 insert key 將某個key加入到該結構,做到不重複加入。delete key 將原本在結構中的某個key移除。getrandom 等概率隨機返回結構中的任何乙個key。要求 insert delete和getrandom方法的時間複雜度都是 o ...
左神演算法筆記01
對數器異或工具 一些其它的位運算子的操作 簡單理解為 將乙個演算法的所有操作拆成基本操作 常數時間完成的操作 後,計算出操作次數和操作時間 可視為1 的乘積,即操作次數之和。在考慮最差情況時用o 來表示時間複雜度,取最高項來表示。如o n o logn 對n個數進行排列,則最差要進行1 2 3 n ...
左神演算法筆記03
可以是函式遞迴,也可以是迴圈實現。將大的陣列對半分為兩個陣列,每個陣列排好序後再合併為大的陣列。如果使用迴圈實現,要提防整形溢位 應用 最小和問題,若陣列的左邊的乙個數比右邊的某乙個數小,在返回結果加上自身的大小 public static intprocess int arr,int l,int ...