题目大意:
给定一个整数数组,1≤a [i]≤n(n =数组的大小),一些元素出现两次,其他出现一次。
查找在该数组中出现两次的所有元素。
算法思想:
因为存储的都是1-n的整数,所以可以利用数组下标进行重复的判断以达到时间复杂度O(N)和空间复杂度O(1)
Java实现:
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> l = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
//将存储的数字作为下标,找到对应位置将其中的数乘-1
//未访问的位置肯定都是正数
//已访问的位置是负数,证明此位置对应的下标+1重复
if (nums[Math.abs(nums[i]) - 1] < 0)
l.add(Math.abs(nums[i]));
else
nums[Math.abs(nums[i]) - 1] *= -1;
}
return l;
}
}
Python3实现:
class Solution:
def findDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
res = []
for x in nums:
if nums[abs(x)-1] < 0:
res.append(abs(x))
else:
nums[abs(x)-1] *= -1
return res
我起初的笨方法(运行时间较短):
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> l = new ArrayList<>();
int j = 0;
int i = 0;
// 设置两个指针,i和j,就初始化为i对应数组下标的存储数字
// j跳向对应数组下标,将值置为零,同时将初始值保存在j中
// j继续跳跃,直到指向的存储值为零(证明此时j的值重复),或者和i指针重合
// i后移到存储值不为零的位置,同时将存储值赋值给j,j进行新一轮的跳跃
// 直到i遍历完所有数组元素为止
while (i < nums.length) {
j = nums[i];
nums[i] = -1;
while (true) {
if (nums[j - 1] == 0) {
l.add(j);
break;
} else if (nums[j - 1] < 0) {
nums[j - 1] = 0;
break;
} else {
int temp = nums[j - 1];
nums[j - 1] = 0;
j = temp;
}
}
while (nums[i] <= 0) {
i++;
if (i == nums.length)
break;
}
}
return l;
}
}