剑指Offer——面试题51:数组中重复的数字

数组中重复的数字


题目:在一个长度为n的数组里的全部数字都在0到n-1的范围内。数组中某些数字是反复的,但不知道有几个数字反复了。也不知道每一个数字反复的次数。请找出数组中随意一个反复的数字。比如假设输入长度为7的数组{2,3,1,0,2,5,3},那么相应的输出是反复的数字2或者3.

输入:{2,3,1,0,2,5,3}

输出:2,3

思路:1、用一次遍历,在遍历数组a的第一个数字2时
2、a[0]和下标0不相符。于是,将a[0]和a[ a[0]=2 ]=1交换,即2放在了对应下标为2的位置
3、而此时a[0]=1,与下标0不符,于是继续将a[0]和a[ a[0]=1 ]交换,即1放在了对应下标为1的位置
4、此时a[0]=3,与下标0不符,于是继续将a[0]和a[ a[0]=3 ]交换,即3放在了对应下标为3的位置
5、此时a[0]=0,与下标0相符,于是交换下一位a[1]

Ps:在这里,有一个地方需要注意,就是比如该数组中没有0怎么办,那么会一直交换,交换到出现重复的数字为止,比如将数组{2,3,1,0,2,5,3}改成{2,3,1,2,2,5,3},那么在交换3和2时,a[0]=2,再下一步时,交换a[0]与a[ a[0]=2 ]时,发现a[0]和a[2]字符是重复了,那么此时将重复字母2存入duplicationNum中,并且开始比较下一个位置(即开始比较a[1])

/*
题目:数组中重复的数字
思路:从0
*/

#include<iostream>
#include<vector>
using namespace std;

void duplicate(vector<int> number, vector<int>& duplicationNum){
    int i = 0;
    while (i < number.size()){
        if (i != number[i]){
            if (number[i] == number[number[i]]){
                bool isSame = false;
                for (int j = 0; j < duplicationNum.size(); j++){
                    if (number[i] == duplicationNum[j]){
                        isSame = true;
                    }
                }
                if (!isSame){
                    duplicationNum.push_back(number[i]);
                }
                i++;
            }
            else{
                swap(number[i], number[number[i]]);
            }
        }
        else{
            i++;
        }
    }
}

int main(){
    //输入数组中的个数
    int n;
    int temp;
    vector<int> number;
    vector<int> duplicationNum;
    cin >> n;
    for (int i = 0; i < n; i++){
        cin >> temp;
        number.push_back(temp);
    }
    duplicate(number, duplicationNum);
    for (int i = 0; i < duplicationNum.size(); i++){
        cout << duplicationNum[i] << " ";
    }
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37885286/article/details/79678117