《剑指Offer》第二版 -- 持续更新

AcWing 13 找出数组中重复的数字

给定一个长度为n的整数数组 nums,数组中所有的数字都在0∼n−1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
注意:如果某些数字不在0∼n−1的范围内,或数组中不包含重复数字,则返回 -1。
数据范围:0 <= n <= 1000

测试样例:

给定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。

返回 2 或 3。

算法思路:

由于题目中的条件“所有的数字都在0~n-1范围内”,因此能够假定如果没有任何重复数字,则数组中的每一个数字都有一个数值相同的下标存在,也就是说:排序之后是一组下标等于数组元素的序列
设定数组为:a[6] = [3, 5, 1, 2, 4, 0],该数组中没有任何重复数字,排序之后为:a_index[6] = [0, 1, 2, 3, 4, 5],符合a[i] = a_index[i],按照样例中的数组来算,排序之后为:[2, 2, 3, 3, 4, 5, 6, 7]对应下标[0, 1, 2, 3, 4, 5, 6, 7],下标0, 1, 2的部分不符合nums[i] = nums_index[i],里面的重复数字为2, 3,其中3 == 3等价于nums[2] == nums[nums[2]],说明原本应该是3的位置已经有一个3了,但是现在又多了一个,因此得出结论3是多出来的数字,数字2同理分析。

代码实现:

class Solution {
public:
    int duplicateInArray(vector<int>& nums) {
        int n = nums.size();
        
        for (auto x : nums) {
            if (x < 0 || x >= n) return -1;
        }

        for (int i = 0; i < n; i++) {
            while (nums[i] != i) {
                if (nums[nums[i]] == nums[i]) {
                    return nums[i];
                }
                swap(nums[i], nums[nums[i]]);
            }
        }    
        return -1;
    }
};

AcWing 14 不修改数组找出重复数字

给定一个长度为n+1的数组nums,数组中所有的数均在1∼n的范围内,其中n≥1。请找出数组中任意一个重复的数,但不能修改输入的数组。
数据范围
1≤n≤1000

样例

给定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。

返回 2 或 3。

算法思路

本题使用二分+抽屉原理实现代码。

抽屉原理:
n + 1个苹果放在n个抽屉里,那么至少有1个抽屉中会放2个苹果。

在本题中,抽屉就是数组长度,苹果就是数组元素,由于长度为n + 1,而数组中元素范围是1~n,因此必有一个数字出现了两次。
1~n分为两个区间[l, mid][mid + 1, r]注意:这里不是分原数组,而是分的数值[1, 2, ..., n],这样分之后由于数组元素有n + 1个并且元素数值有n个,因此一定存在落在其中一个区间的数的个数大于该区间应有的长度
接着遍历原数组,计算出有多少个数字落在区间[l, mid]中,如果发现落在该区间数字数量s >= mid - l + 1,就说明重复数字一定出现在区间[l, mid]中。

代码实现

class Solution {
public:
    int duplicateInArray(vector<int>& nums) {
        int l = 1, r = nums.size() - 1; // 长度nums.size()为n + 1
        while (l < r) {
            int mid = l + r >> 1;
            int s = 0;
            for (auto num : nums) s += num >= l && num <= mid;
            if (s > mid - l + 1) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};
posted @ 2026-07-05 14:02  uiwhiuhweur  阅读(2)  评论(0)    收藏  举报