第 4 天 查找算法(简单)

139 阅读1分钟

剑指 Offer 03. 数组中重复的数字

思路:

因为所有数字都在 0~n-1 的范围内,且正好有n个数字,也就是说

每个数字都可以放在自己大小所对应的位置上

因此我们可以直接遍历数组

将遍历到的数字放在他们对应的位置上,如果发现对应位置被与自己相同的数字占了 就说明有重复数字

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

剑指 Offer 53 - I. 在排序数组中查找数字 I

思路:

简单的二分模板题,通过二分,找到第一个大于等于target的位置x1,再找到第一个大于target的位置x2, ans=x2-x1

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(!nums.size()) return 0;
        int l=0,r=nums.size()-1;
        // 先找第一个大于等于target的下标
        while(l<r){
            int mid=l+r>>1;
            if(nums[mid]>=target) r=mid;
            else l=mid+1;
        }
        // 如果nums[l]依然不满足 >= target
        // x1就还要后移一位
        int x1=l+!(nums[l]>=target);
        l=0,r=nums.size()-1;
        // 找第一个大于target的下标
        while(l<r){
            int mid=l+r>>1;
            if(nums[mid]>target) r=mid;
            else l=mid+1;
        }
        int x2=l+!(nums[l]>target);
        return x2-x1;
    }
};
class Solution {
    public int search(int[] nums, int target) {
        if(nums.length==0) return 0;
        int l=0,r=nums.length-1;
        while(l<r){
            int mid=l+r>>1;
            if(nums[mid]>=target) r=mid;
            else l=mid+1;
        }
        int x1=l;
        if(! (nums[l]>=target) ) x1++;

        l=0;
        r=nums.length-1;
        while(l<r){
            int mid=l+r>>1;
            if(nums[mid]>target) r=mid;
            else l=mid+1;
        }
        int x2=l;
        if(! (nums[l]>target) ) x2++;
        return x2-x1;
    }
}

剑指 Offer 53 - II. 0~n-1中缺失的数字

思路:

直接对数组求和,再通过等差数列前n项和公式减去数组值即可

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        int sm=n*(n+1)/2;
        for(auto it:nums) sm-=it;
        return sm;
    }
};
class Solution {
    public int missingNumber(int[] nums) {
        int n=nums.length;
        int sum=(n*(n+1))/2;
        for(int i=0;i<nums.length;i++){
            sum-=nums[i];
        }
        return sum;
    }
}