【剑指offer】 03 数组中重复的数字

【剑指offer】 03 数组中重复的数字

3-1 题目

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

思考

  • 解法1:我直接一看就打算暴力了,开一个数组or字典记录每个出现过的数字,直接扫一边即可获得答案,时间复杂度为O(n),空间复杂度也是O(n)
  • 我没有考虑其他的解法,还有其他两种空间复杂度为O(1)的解法:
  • 解法2:排序,然后看这个数字和上一个数字是不是一样。时间复杂度为O(nlogn),空间复杂度为O(1)
  • 解法3:鸽巢原理(原地置换、原地哈希)。因为这个题目比较特殊,长度为n而且所有数字都在0~n-1里面,所以如果没有重复的数字的话,这个数组排序之后每个元素和其下标是一一对应的(元素值==下标值)。如果有重复的元素的话,有的元素无法再放在其值下标的位置的,因为那里面已经有了一个相同值的元素了。
    • 如果当前这个元素值不等于其下标
      • 如果其值对应下标不等于其值,则交换(则这个值可以放到相应下标的位置里了)
      • 如果其值对应下标等于其值,找到重复元素
    • 如果当前这个元素值等于其下标,则判断下一个下标的元素
  • 三种解法的效果,其中第一行为解法三,第二行为解法2,第三行为解法1的map实现,第四行为解法1的布尔数组实现。
    • image-20210113161446493

代码

解法1

  • 发现直接用一个O(n)的布尔数组(下),比用map(上)的效果更好,所以最好还是少用STL(盲猜?)
    • image-20210113160159137
  • 容器访问最好直接用下标访问,有些情况会明显下标更快
class Solution {
    bool a[100005];
public:
    int findRepeatNumber(vector<int>& nums) {
        memset(a,0,sizeof(a));
        int ret=0;
        // 最好是直接下标访问,一些情况会明显比用迭代器快
        // 我写这个代码的时候不知道hhh
        for(vector<int>::iterator it=nums.begin(); it!=nums.end(); it++){
            if(a[*it]){
                printf("%d
",*it);
                ret = *it;
                break;
            }
            else{
                a[*it]=true;
            }
        }
        return ret;
    }
};

解法2

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int pre = nums[0];
        for(int i=1;i<nums.size();i++){
            if(nums[i]==pre) return pre;
            pre = nums[i];
        }
        return 0;
    }
};

解法4

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        for(int i=0;i<nums.size();i++)
        {
            while(i!=nums[i]){
                if(nums[nums[i]]==nums[i]){
                    return nums[i];
                }
                else{
                    swap(nums[i], nums[nums[i]]);
                }
            } 
        }
        return 0;
    }
};
原文地址:https://www.cnblogs.com/xuwanwei/p/14272711.html