剑指Offer刷题记录_day4

剑指Offer刷题记录_day4

简单查找

Q1 查找数组重复元素

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

简单思路1:采用空间换时间,开辟数组记录出现次数,出现第一个大于1时则返回;未找到则返回-1;

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {

        int num[100001];
        for(int i = 0; i < 10001; i++)
          num[i] = 0;
        for(int i = 0; i < nums.size(); i++)
          {
              if(++num[nums[i]] > 1) return nums[i];
          }
        return -1;
    }
};

Better idea : 遍历数组并通过交换操作,使元素的 索引 一一对应(即 nums[i] = inum**s[i]=i )。因而,就能通过索引映射对应的值,起到与字典等价的作用。

  • 遍历数组 numsnums ,设索引初始值为 i = 0i=0 :

  • 若 nums[i] = inums[i]=i : 说明此数字已在对应索引位置,无需交换,因此跳过;

  • 若 nums[nums[i]] = nums[i]nums[nums[i]]=nums[i] : 代表索引 nums[i]nums[i] 处和索引 ii 处的元素值都为 nums[i]nums[i] ,即找到 一组重复值,返回此值 nums[i]nums[i] ;

  • 否则: 交换索引为 ii 和 nums[i]nums[i] 的元素值,将此数字交换至对应索引位置。

  • 若遍历完毕尚未返回,则返回 -1

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

Q2统计一个数字在排序数组中出现的次数

有序数组首先该想到是二分查找:两次二分查找确定指定数字数组边界,然后做差

class Solution {
    public int search(int[] nums, int target) {
        if(nums.length == 0) {
            return 0;
        }
        //初始左右指针位置
        int i = 0;
        int j = nums.length-1;
        //第一次二分:找right边界
        while(i <= j) {
            int mid = (i+j) >> 1;
            if(nums[mid] <= target){
                i = mid+1;
            }
            else{
                j = mid-1;
            }
        }
        if(j>=0&&nums[j] != target){
            return 0;
        }
        int right = i;    //更新right边界
        //重置指针
        i = 0;
        //第二次二分:找left边界
        while(i <= j) {
            int mid = (i+j) >> 1;
            if(nums[mid] >= target){
                j = mid-1;
            }
            else{
                i= mid+1;
            }
        }
        //更新左指针
        int left = j;
        return right-left-1;
    }
}

Q3 0~n-1中缺失的数字

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

基本思路:有序数组,整体框架还是使用二分查找;根据题目,若不缺的话数组0-n-1的位置上正好是0-n-1;

​ 而现在是缺少一个数,即从某个数开始,下标和数字就开始不对应了,由此出发可以设置二分查找的判断条件.

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

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值