這道演算法題太太太太太簡單啦

程式設計師吳師兄發表於2019-05-17

本文首發於公眾號「五分鐘學演算法」,是圖解 LeetCode 系列文章之一。

個人網站:www.cxyxiaowu.com

今天分享一道很簡單的演算法題。

題目來源於 LeetCode 上第 268 號問題:缺失數字。題目難度為 Easy,目前通過率為 50.2% 。

題目描述

給定一個包含 0, 1, 2, ..., nn 個數的序列,找出 0 .. n 中沒有出現在序列中的那個數。

說明:

你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?

這道演算法題太太太太太簡單啦

題目解析

這道題目有三種解法。

解法一:異或法

和之前那道 只出現一次的數字 很類似:

只出現一次的數字: 給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。

如果我們補充一個完整的陣列和原陣列進行組合,那所求解的問題就變成了 只出現一次的數字

將少了一個數的陣列與 0 到 n 之間完整的那個陣列進行異或處理,因為相同的數字異或會變為了 0 ,那麼全部數字異或後,剩下的就是少了的那個數字。

這道演算法題太太太太太簡單啦

程式碼實現1

class Solution {
    public int missingNumber(int[] nums) {
        int res = 0;
        //注意陣列越界情況
        for (int i = 0; i < nums.length;i++){
            // i 表示完整陣列中的數字,與原陣列中的數字 nums[i] 進行異或,再與儲存的結果異或
            res = res^i^nums[i];
        }
        //最後需要與迴圈中無法使用到的那個最大的數異或
        return res^i;
    }
}
複製程式碼

程式碼實現2

class Solution {
   public int missingNumber(int[] nums) {
    int res = nums.length;
    for (int i = 0; i < nums.length; ++i){
        res ^= nums[i];
        res ^= i;
    }
    return res;
  }
}
複製程式碼

解法二:求和法

  • 求出 0 到 n 之間所有的數字之和
  • 遍歷陣列計算出原始陣列中數字的累積和
  • 兩和相減,差值就是丟失的那個數字

這道演算法題太太太太太簡單啦

//小吳之前擔心會資料溢位,不過估計這題考察的不是這個,所以測試用例沒寫這種吧,還是能 AC 的
class Solution {
   public int missingNumber(int[] nums) {
        int n = nums.length;
        int sum = (n+0)*(n+1)/2;
        for (int i=0; i<n; i++){
            sum -= nums[i];
        }
        return sum;
 }
}
複製程式碼

解法三:二分法

將陣列進行排序後,利用二分查詢的方法來找到缺少的數字,注意搜尋的範圍為 0 到 n 。

  • 首先對陣列進行排序
  • 用元素值和下標值之間做對比,如果元素值大於下標值,則說明缺失的數字在左邊,此時將 right 賦為 mid ,反之則將 left 賦為 mid + 1 。

注:由於一開始進行了排序操作,因此使用二分法的效能是不如上面兩種方法。

public class Solution {
    public int missingNumber(int[] nums) {
        Arrays.sort(nums);
        int left = 0;
        int right = nums.length;
        while (left < right){
            int mid = (left + right) / 2;
            if (nums[mid] > mid){
                right = mid;
            }else{
                left = mid + 1;  
            }
        }
        return left;
    }
}
複製程式碼

相關文章