数组中重复的数据

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中重复的数据相关的知识,希望对你有一定的参考价值。

数组中重复的数据

数据结构和算法 2022-05-16 18:40
问题描述

来源:LeetCode第442题
难度:中等

给你一个长度为n的整数数组nums,其中nums的所有整数都在范围[1,n]内,且每个整数出现一次或两次。请你找出所有出现两次的整数,并以数组形式返回。

你必须设计并实现一个时间复杂度为O(n)且仅使用常量额外空间的算法解决此问题。

示例 1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[2,3]


示例 2:
输入:nums = [1,1,2]
输出:[1]

示例 3:
输入:nums = [1]
输出:[]

提示: n == nums.length 1 <= n <= 10^5 1 <= nums[i] <= n nums 中的每个元素出现一次或两次

问题分析

这题说的是找出重复的数字,本来看起来很简单的一道题,但因为题中要求必须实现一个时间复杂度为O(n)且仅使用常量额外空间的算法解决此问题,所以通过排序或者是用集合Map首先被排除掉。

我们再来仔细看这道题,他说的数组nums中所有整数都在[1,n]内,我们可以把数组中的元素num放到第num个位置,因为数组的下标是从0开始的,也就是把元素num放到数组下标为num-1的位置。因为一个位置只能放一个元素,如果某个元素出现了两次,那么肯定有一次是放在其他位置的。最后我们只需要找出元素和下标不匹配的即可。

来看下代码

public List<Integer> findDuplicates(int[] nums) 
    int length = nums.length;
    for (int i = 0; i < length; ++i) 
        //把当前元素放到对应的位置
        while (nums[i] != nums[nums[i] - 1]) 
            swap(nums, i, nums[i] - 1);
        
    
    List<Integer> res = new ArrayList<>();
    // 如果当前元素的值和对应的下标不一致,说明出现了两次
    for (int i = 0; i < length; ++i) 
        if (nums[i] - 1 != i) 
            res.add(nums[i]);
        
    
    return res;


public void swap(int[] nums, int i, int j) 
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;


其实还有一种方式,就是我们不交换,直接把对应位置的值变为负的,后面如果遇到对应位置为负的就说明出现了重复的。直接画个图看下

看下代码

public List<Integer> findDuplicates(int[] nums) 
    List<Integer> res = new ArrayList<>();
    for (int i = 0; i < nums.length; i++) 
        int index = Math.abs(nums[i]) - 1;
        // 如果当前位置的值是负数,说明出现过重复的
        if (nums[index] < 0) 
            res.add(index + 1);
            continue;
        
        nums[index] = -nums[index];
    
    return res;

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于数组中重复的数据的主要内容,如果未能解决你的问题,请参考以下文章

删除顺序数组的重复数字

获取 GPS 位置坐标并存储在数组中 [重复]

在目标c中订购一个数组/字典[重复]

数组中重复的数字

剑指Offer03. 数组中重复的数字(哈希)

剑指Offer03. 数组中重复的数字(哈希)