解法一、原地哈希
直接沿用了上一道题(找消失数字)的思路!
特征:规范数据为1-n,因此可以原数组哈希,做到有限额外空间。遍历两次,时间复杂度O(n)。中等题应该是因为时间和空间复杂度的局限
做法:+len表达它有出现,len是因为是最大数据,还原数据需要取模。*这里后来发现定义一个len+1的常量表示模,思路上更清晰。大于二倍长度代表出现两次,小于等于三倍代表第一次在结果列表里出现。
对比了for循环的两种写法,第一种强度了数据本身,第二种强调了依次,感觉第一次留意这种细节。第二次循环里的条件<=是规避边界情况(num[i]里的数字正好等于len,如[2,2])。
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new LinkedList<>();
int len = nums.length;
for(int num : nums){
nums[(num - 1) % len] += len;
}
for(int i = 0;i < len;i++){
if(nums[i] > 2 * len && nums[i] <=3 * len){
res.add(i + 1);
nums[i] += len;
}
}
return res;
}
}
解法二、 交换数字
如果当前位置的数字不是下标+1的数字,那么把它放进它对应的地方。
如[1,4,3,2,4,5,3,2]交换后变成[1,2,3,4,5,4,3,2]
最后不在正确的位置上的数字就是多出来的数字。(这个可以用来做消失数字题,改改res时if条件)
class Solution {
public List<Integer> findDuplicates(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; ++i) {
while (nums[i] != nums[nums[i] - 1]) {
swap(nums, i, nums[i] - 1);
}
}
List<Integer> ans = new ArrayList<Integer>();
for (int i = 0; i < n; ++i) {
if (nums[i] - 1 != i) {
ans.add(nums[i]);
}
}
return ans;
}
public void swap(int[] nums, int index1, int index2) {
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/find-all-duplicates-in-an-array/solutions/1473718/shu-zu-zhong-zhong-fu-de-shu-ju-by-leetc-782l/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解法三、正负号
第一次加负号,已负号直接放入ans。重复出现问题(两次)可选,但选择消失的数字的题不行
class Solution {
public List<Integer> findDuplicates(int[] nums) {
int n = nums.length;
List<Integer> ans = new ArrayList<Integer>();
for (int i = 0; i < n; ++i) {
int x = Math.abs(nums[i]);
if (nums[x - 1] > 0) {
nums[x - 1] = -nums[x - 1];
} else {
ans.add(x);
}
}
return ans;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/find-all-duplicates-in-an-array/solutions/1473718/shu-zu-zhong-zhong-fu-de-shu-ju-by-leetc-782l/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
碎碎念
- 增加了对for循环写法的理解
- 用上了上道题的解法,巩固了原地哈希的印象(数组是0到n-1有时绕不过来··)
- 第一道中难度题!++信心(
真的非常、非常感谢点赞、收藏甚至关注的站友,自己清楚写得非常潦草,任何记录的回馈都给了很大的信心与鼓励。一开始上手时,看着很多秒简单甚至手撕困难的人,也觉得有点不好意思继续;但反向思考,想着这样写下来,也有路过的人会觉得「写这么差的人居然还在写题」从而得到激励、更认可自己的能力,也算是另一种价值所在吧。