统计数组中的元素——442.数组里重复的数据


解法一、原地哈希

直接沿用了上一道题(找消失数字)的思路!

特征:规范数据为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有时绕不过来··)
  • 第一道中难度题!++信心(

真的非常、非常感谢点赞、收藏甚至关注的站友,自己清楚写得非常潦草,任何记录的回馈都给了很大的信心与鼓励。一开始上手时,看着很多秒简单甚至手撕困难的人,也觉得有点不好意思继续;但反向思考,想着这样写下来,也有路过的人会觉得「写这么差的人居然还在写题」从而得到激励、更认可自己的能力,也算是另一种价值所在吧。

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值