LeetCode#442 Find All Duplicates in an Array题解(C++版)

题干

这里写图片描述

原题网址:
https://leetcode.com/problems/find-all-duplicates-in-an-array/description/

题干解析

给你一个数组,数组内的数据大小满足大于等于1且小于等于n(n为数组的长度)。且数据要么出现了一次,要么出现了两次,要你找出所有出现了两次的数值,并返回。
要求:不用新的空间,并在O(n)的时间复杂度内完成。

难度

中等

解题思路

本题乍一看以为不难,仔细一看要求挺苛刻的:不能用新的空间,而且时间复杂度要求O(n),所以不能用简单的计数来实现,也不能暴力搜索来实现,解这道题还是需要一些技巧的。
注意到这个数组的数据的大小要求比较严格,可以从这里进入作为突破点。因为数据的大小不会超过数组的长度,自然而然地想起了桶排的思想,但是不能用新的空间,只能在这个数组进行操作,所以,我考虑从数组头部(下标为0处,即i=0)开始往后遍历,设该位置为 i ,得到i位置的数值,找到该数值对应的坐标(如示例的第一个数值为4,那么找的下标应该是3,因为数组的下标是从0开始的,所以下标为3代表第4个),将找到的下标的位置做个标记(代码中我给它标为-1),但是这时候我们就要考虑到保护原来在下标为3的那个位置的数值(如果有未使用过的数值的话),既然当下 i 位置数值已经被用过了,那么当下 i 位置相当于是无用的,所以可以把下标为3的那个位置的数值放到当下 i 位置。这样往后遍历,如果出现这种情况,找到的下标的位置已经置为-1,说明该数值前面已经出现过了,所以这个数据就是我们要找的数据,将它放入要返回的矢量中。

代码

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> ans;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] != -1) {
                int temp;
                if (nums[nums[i] - 1] != -1) {  // 如果此位置还有有效的数值
                    temp = nums[i] - 1;
                    nums[i] = 0;
                    if (nums[temp] != 0) {
                        nums[i] = nums[temp]; //把需要保护的数值放到现在的位置
                        i--; // 待会重新返回当下位置
                    }
                    nums[temp] = -1;  //将找到的下标位置置为-1
                } else {
                    ans.push_back(nums[i]);  // 找到的重复的值放入数组中
                    nums[i] = 0; // 表示该位置为空
                }
            } 
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值