LeetCode演算法題-Missing Number(Java實現-四種解法)
這是悅樂書的第200次更新,第209篇原創
01 看題和準備
今天介紹的是LeetCode演算法題中Easy級別的第65題(順位題號是268)。給定一個包含n個不同數字的陣列,取自0,1,2,...,n,找到陣列中缺少的數字。例如:
輸入:[3,0,1]
輸出:2
輸入:[9,6,4,2,3,5,7,0,1]
輸出:8
注意:您的演算法應該以線性執行時複雜性執行。 你能用恆定的額外空間複雜度來實現嗎?
本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。
02 第一種解法
特殊情況:當nums為null的時候,或者nums中沒有元素的時候,直接返回0即可。
正常情況:缺失的數字分為三種情況:一是缺失的數字在中間,比如{0,1,2,4},此時缺失的數字是3;二是缺失的數字在末尾,比如{0,1,2,3},此時缺失的數字就是4;三是缺失的數字在頭部,比如{1,2,3,4},此時缺失的數字就是0。
先將陣列從小到大排序,然後使用for迴圈,判斷索引是否相等,不相等就是中間缺失的那個數,如果中間不缺數,最後返回索引即可,因為已經在迴圈體中自加1,最後返回的時候不用再加1。
此解法時間複雜度是O(nlog(n)),空間複雜度是O(1)。
public int missingNumber(int[] nums) { if (nums == null || nums.length < 1) { return 0; } Arrays.sort(nums); int index; for (index = 0; index < nums.length; index++) { if (index != nums[index]) { return index; } } return index; }
03 第二種解法
通過觀察,我們可以發現,nums中的元素組成是一個以1為等差的等差數列,我們可以通過等差數列的和來找出缺失的元素,其求和公式為:
Sum = n*(A1+An)/2
題目中的陣列是從0開始到n,即A1=0,An=n-1,我們計算的時候可以從1到陣列長度,即A1=1,An=n,然後對其求和,藉助for迴圈,此處有兩種方式,一是用和去減每一個元素,最後剩下的就是缺失的元素;二是算出陣列所有元素的和,再算等差數列的和與其的差值,就是缺失的元素。
此解法的時間複雜度是O(n),空間複雜度是O(1)。
public int missingNumber2(int[] nums) { if (nums == null || nums.length < 1) { return 0; } int sum = (nums.length*(1+nums.length))/2; for (int n : nums) { sum -= n; } return sum; }
04 第三種解法
藉助位運算中的異或(^)運算,通過一個運算公式:a^b^b = a
,我們可以算出缺失的那個數字。例如:
陣列nums={0,1,2,4},陣列的索引是{0,1,2,3}
missing=4^(0^0)^(1^1)^(2^2)^(4^3)
=3^(0^0)^(1^1)^(2^2)^(4^4)
=3
其中最開始的4就是陣列的長度。
此解法的時間複雜度是O(n),空間複雜度是O(1)。
public int missingNumber3(int[] nums) {
if (nums == null || nums.length < 1) {
return 0;
}
int xor = nums.length;
for (int i = 0; i < nums.length; i ++) {
xor = xor ^ nums[i] ^ i;
}
return xor;
}
05 第四種解法
使用HashSet,先將陣列中的每一個元素存入其中,然後利用for迴圈,從0到n,判斷set中是否包含當前索引,不包含的就是缺失的那個數。
此解法也可以用HashMap做,思路都是一樣的,時間複雜度是O(n),空間複雜度是O(n)。
public int missingNumber4(int[] nums) {
if (nums == null || nums.length < 1) {
return 0;
}
Set<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
for (int i=0; i<=nums.length; i++) {
if (!set.contains(i)) {
return i;
}
}
return -1;
}
06 小結
演算法專題目前已連續日更超過一個月,演算法題文章65+篇,公眾號對話方塊回覆【資料結構與演算法】、【演算法】、【資料結構】中的任一關鍵詞,獲取系列文章合集。
以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!