数组中重复的数据
Posted 勇敢*牛牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中重复的数据相关的知识,希望对你有一定的参考价值。
数组中重复的数据
数据结构和算法 2022-05-16 18:40
问题描述
来源:LeetCode第442题
难度:中等
给你一个长度为n
的整数数组nums
,其中nums
的所有整数都在范围[1,n]
内,且每个整数出现一次或两次。请你找出所有出现两次的整数,并以数组形式返回。
示例 1:你必须设计并实现一个时间复杂度为O(n)且仅使用常量额外空间的算法解决此问题。
输入: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周边激励大奖
以上是关于数组中重复的数据的主要内容,如果未能解决你的问题,请参考以下文章