1. 程式人生 > 其它 >劍指Offer-第4天 查詢演算法(簡單)

劍指Offer-第4天 查詢演算法(簡單)

第一題

題目連結:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

個人題解:索引法

  1. 我們可以將數字和下表進行對應,每次把索引和下標一樣的數字記錄(強行變成)
  2. 當我們再次遍歷的時候如果下標一樣,就一定會有重複,返回其中一個即可。

程式碼:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int i=0,n=nums.size();
        while(i<n){
            if(nums[i]==i) {
                i++;
                continue;
            }
            if(nums[nums[i]]==nums[i]) return nums[i];
            swap(nums[i],nums[nums[i]]);
        }
        return -1;
    }
};

結果:

第二題

題目連結:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/ (其實挺好奇為什麼他的題目的英文描述是拼音hhh)

個人題解:二分查詢即可,時間複雜度 \(O(logN)\) (可以呼叫函式也可以手寫)

程式碼:


class Solution {
public:
    int search(vector<int>& nums, int target) {
        return upper_bound(nums.begin(), nums.end(), target) 
             - lower_bound(nums.begin(), nums.end(), target);
    }
};

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(!nums.size()) return 0;

        int le=0,ri=nums.size()-1;
        while(le<ri){
            int mid=ri+le>>1;
            if(nums[mid]>=target) ri=mid;
            else le=mid+1;
        }

        if(nums[ri]!=target) return 0;

        int idx=le;

        le=0,ri=nums.size()-1;
        while(le<ri){
            int mid=ri+le+1>>1;
            if(nums[mid]<=target) le=mid;
            else ri=mid-1;
        }

        int idx1=ri;

        return idx1-idx+1;
    }
};

結果:(第一張圖呼叫函式,第二張圖手寫,手寫快了一點)

第三題

題目連結:https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/

個人題解:二分查詢,如果數字和下標一樣則繼續,反之退出

程式碼:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int i=0,j=nums.size()-1;
        while(i<=j){
            int mid=i+j>>1;
            if(nums[mid]==mid) i=mid+1;
            else j=mid-1;
        }
        return i;
    }
};

結果: