每日一题——找出数组中重复的数字

245 阅读1分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

题目

文字描述

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

示例 1:

输入: [2, 3, 1, 0, 2, 5, 3] 输出:

2 或 3

限制:2 <= n <= 100000

思路

我对这道题的思考是先把整个数组进行排序,然后在进行一次循环遍历,如果num[i] == num[i + 1],就可以得出结果;最近学会了哈希值的离散存储,我觉得可以把数组中的每个值进行哈希计算得出哈希值存入哈希数组中,当第二个存入hash数组中的数即是我们想要的答案,这样的代码实现可以把原先的两重循环缩减至一重。

代码实现

第一种思路代码实现:

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

    }
};

第二种思路的代码实现:

思路:

从头到尾扫描数组中的数字,每扫描一个数字,就用O(1)的时间去判断哈希表里是否包含该数字,如果哈希表里已经存在该数字,就找到一个重复的数字,如果哈希表里面没有这个数字,就把它加入哈希表。这个思路的时间复杂度为O(n),空间复杂度为O(n)

注意:这里用来存放哈希离散后的数组需要勇memeset函数把其内部全部变为零,这样方便我们的操作与基本的计算

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int n = 100010;
        int q[n];
        memset(q,0,sizeof(q)); // 把用来存放哈希值得数组内部全置为0
        int length = nums.size(), result = 0;
        for(int i = 0;i < length;i ++)
        {           
            //  把每一个值哈希后存入
            int x = (nums[i] % n + n) % n;
            //cout << q[i] << endl;
            if(q[x] == 0) q[x] = nums[i];
            else{
                result = nums[i];
                break;
            }
        }
        return result;
    }
};