0
点赞
收藏
分享

微信扫一扫

(剑指offer)JZ3 数组中重复的数字[cpp实现]

JZ3 数组中重复的数字


1. 题目描述

数据范围:0≤n≤10000
进阶:时间复杂度O(n),空间复杂度O(n)


2. 运行示例


3. 解决方法


3.1 方法一

     思路:最容易想到的一种方法,对数组中的数据进行排序,然后一次遍历,比较找出第一个重复的数字进行返回。


代码实现:

int duplicate(vector<int>& numbers) {
    // write code here
    sort(numbers.begin(),numbers.end()); // 从小到大排序
    for(int i = 1;i<numbers.size();++i) // 这里从1开始
        if(numbers[i-1]==numbers[i]) // 判断当前数字是否和前面一个相同 即出现重复
            return numbers[i];
    return -1;
}

时间复杂度:O(nlogn)


3.2 方法二

     思路:使用set集合,如果set集合中没有当前数字,那么将其加入到set集合中;
如果出现了当前数字,那么当前数字即出现重复,返回当前数字。

这里简单说明一下set集合的使用:set集合中将数据从大到小排列,且不含重复元素。


代码实现:

int duplicate(vector<int>& numbers) {
    // write code here
    set<int> s;
    for(int i=0;i<numbers.size();++i){ // 遍历numbers
        if(s.find(numbers[i]) == s.end()) // 如果find查询当前元素返回的是end迭代器 那么即集合中不含当前元素
           s.insert(numbers[i]); // 将当前元素插入到set集合中
        else
           return numbers[i]; // 否则返回当前元素
    }
    return -1;
}

时间复杂度:O(n)


3.3 方法三

     思路:注意题目中的一句话:“在一个长度为n的数组里的所有数字都在0到n-1的范围内。”,那么现在可以将元素和对应容器的下标对应起来,比如:

     从头开始遍历数据,如果当前元素值和对应其下标值不相同,并且当前元素值和用当前元素作为下标的那个元素值不相同的话,那么将当前元素和与用当前元素做下标的元素进行交换,从而得到了一个数组下标和元素对应的数据;如果相同,那么继续查看下一元素,因此,上面举例可以进行如下变换:

     此时如果再进行一次变换,可以发现[0]中元素2和[2]中元素2出现了重复,那么则返回该重复元素。


代码实现:

    int duplicate(vector<int>& numbers) {
        // write code here
        for(int i = 0;i<numbers.size();++i){
            while(numbers[i]!=i){
                if(numbers[i] == numbers[numbers[i]])
                    return numbers[i];
                else
                    swap(numbers[i],numbers[numbers[i]]);
            }
        }
        return -1;
    }

时间复杂度:O(n)


自己感觉第三中方法叙述解释的不是太好,欢迎批评指正。

——————END-2022-05-01——————

举报

相关推荐

0 条评论