Leetcode——287. 寻找重复数

首先很简单的做法即用哈希表记录数字出现的次数,最后循环哈希表输出value值不为1的key值。

cpp 复制代码
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        unordered_map<int, int> map;
        for(int x : nums){
            map[x]++;
        }
        for(auto& entry : map){
            if(entry.second != 1){
                return entry.first;
            }
        }
        return 0;
    }
};

接着就是考虑高效算法,这里可以将数组看作一个链表,这个思想确实很巧妙,但也很难考虑到。

当看作是一个链表时,其任务就是找链表的环了。

如果允许修改原数组,即我们可以标记负号表示已经来过。

cpp 复制代码
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int idx = 0;
        while(nums[idx] > 0){
            int old = idx;
            idx = nums[old];
            nums[old] = -nums[old];
        }
        return idx;
    }
};

如果不允许修改原数组,则用快慢指针找环即可。

cpp 复制代码
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int slow = 0;
        int fast = 0;
        do{
            slow = nums[slow];
            fast = nums[nums[fast]];
        }while(slow != fast);
        
        fast = 0;
        while (fast != slow) {
            fast = nums[fast];
            slow = nums[slow];
        }
        return slow;
    }
};

注意,双指针解法需要从同一位置出发。

当然,此题也可用二分查找求解。

由于我们要找的数范围为[1, n],所以取mid,遍历数组,如果<=mid的数字个数小于count,则说明[1, mid]范围上有数字少了,所以重复数字在[mid, n]区间。

cpp 复制代码
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int len = nums.size();
        int left = 0, right = len - 1;
        while(left < right){
            int mid = left + ((right - left) >> 1);
            int count = 0;
            for(int x : nums){
                if(x <= mid){
                    count++;
                }
            }
            if(count > mid){
                right = mid;
            }else{
                left = mid + 1;
            }
        }
        return left;
    }
};
相关推荐
charlie1145141911 小时前
精读 C++20 设计模式:行为型设计模式 — 访问者模式
c++·学习·设计模式·访问者模式·c++20
linux kernel3 小时前
第二十三讲:特殊类和类型转换
开发语言·c++
渡我白衣3 小时前
深入剖析:boost::intrusive_ptr 与 std::shared_ptr 的性能边界和实现哲学
开发语言·c++·spring
怀旧,4 小时前
【C++】26. 智能指针
开发语言·c++·算法
dragoooon344 小时前
[优选算法专题三.二分查找——NO.24搜索旋转排序数组中的最⼩值]
数据结构·leetcode·动态规划
Haooog4 小时前
654.最大二叉树(二叉树算法)
java·数据结构·算法·leetcode·二叉树
Swift社区4 小时前
LeetCode 392 判断子序列
算法·leetcode·职场和发展
楼田莉子5 小时前
vscode搭建C/C++配置开发环境
c语言·开发语言·c++·vscode·学习·编辑器
R-G-B5 小时前
【14】C#实战篇——C++动态库dll 接口函数将char* strErr字符串 传给C# ,并且在winform的MessageBox和listbox中显示。C++ string 日志传给 C#
c++·c#·strerr字符串传给c#·动态库dll传递字符串给c#·string日志传给c#·c++ string传给 c#·c++底层函数日志传给c#显示
半桔5 小时前
【STL源码剖析】从源码看 list:从迭代器到算法
java·数据结构·c++·算法·stl·list