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

 

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

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

題目描述

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

說明:算法

你的算法應該具備線性時間複雜度。 你能夠不使用額外空間來實現嗎?數組

題目解析

這道題目有三種解法。性能

解法一:異或法

和以前那道 只出現一次的數字 很相似:測試

只出現一次的數字: 給定一個非空整數數組,除了某個元素只出現一次之外,其他每一個元素均出現兩次。找出那個只出現了一次的元素。網站

若是咱們補充一個完整的數組和原數組進行組合,那所求解的問題就變成了 只出現一次的數字spa

將少了一個數的數組與 0 到 n 之間完整的那個數組進行異或處理,由於相同的數字異或會變爲了 0 ,那麼所有數字異或後,剩下的就是少了的那個數字。3d

代碼實現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;
    }
}

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

我的網站:https://www.cxyxiaowu.com

相關文章
相關標籤/搜索