LeetCode 442 数组中重复的数据C++解

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

// 长度为n的数组,每个数值都在1~n范围内,找出其中重复的元素

// 方法一:
// hash表实现(set) 空间复杂度较高
// 或者组数标记,出现且为0置1,为1则说明存在
vector<int> find_dup1(int arr[], int n){
    unordered_set<int> s;
    vector<int> res;
    if (n == 0 || n == 1) {
        return res;
    }
    for (int i = 0; i < n; ++i){
        if (!s.count(arr[i])){
            s.insert(arr[i]);
        }
        else{
            res.push_back(arr[i]);
        }
    }
    return res;
}

// 方法二
// 基数排序的思想,但是限制是只能找到一个重复元素,否则输出结果会重复
int find_dup2(int arr[], int n){

    if (n == 0 || n == 1) return -1;
    int i = 0;
    while (i < n){
        if (arr[i] == i+1){
            ++ i;
            //continue;
        }
        else{
            if (arr[i] == arr[arr[i]-1]){

                return arr[i];
            }
            else{
                // void swap(int &a, int &b);
                swap(arr[i], arr[arr[i]-1]);
            }
        }
    }
    return -1;
}

//方法三
// 思路:遍历数组,将(元素-1)作为下标访问对应元素,并将该元素设置为相反数
// 则下次有重复元素的时候(元素-1)作为下标访问对应元素的时候,该元素已经为负
// 则找到了重复元素
// 注意,将元素作为下标访问时,应该取绝对值,因为可能为负,无法作为索引
vector<int> find_dup3(vector<int> nums){
    vector<int> res;
    int n = nums.size();
    if (n == 0 || n == 1) return res;
    for (int i = 0; i < n; ++i){
        int j = nums[i];
        j = abs(j);
        if (nums[j-1] > 0){
            nums[j-1] = -nums[j-1];
        }
        else{
            res.push_back(j);
        }
    }
    return res;
}



int main()
{
    int arr[7] = {1,3,4,3,2,2,6};

    // 一
    vector<int> res1 = find_dup1(arr, 7);
    //int n = res.size();
    for (size_t i = 0; i < res1.size(); ++i){
        cout<<res1[i]<<" ";
    }
    cout<<endl;

    // 二
    cout<<find_dup2(arr, 7)<<endl;

    // 三
    vector<int> nums(arr, arr+7);
    vector<int> res3 = find_dup3(nums);
    for (size_t i = 0; i < res3.size(); ++i){
        cout<<res3[i]<<" ";
    }
    cout<<endl;

    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值