《算法分析与设计》Week 1

442. Find All Duplicates in an Array


Description:

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements that appear twice in this array.

Could you do it without extra space and in O(n) runtime?

Example:

Input:
[4,3,2,7,8,2,3,1]

Output:
[2,3]

Solution:

一、题意理解

      给定一个size为n的整型数组,1 ≤ a[i] ≤ n,,即数组中的所有元素均在[1, n]之间。一些元素出现了两次,其它元素均只出现了一次。找到这些出现了两次的元素。要求空间复杂度为O(1),时间复杂度为O(n)。


二、分析

    1、首先想到的解法是排序,排序后相同的元素会相邻,然后依次遍历,就能找到这些重复的元素,但是这样时间复杂度最低也为O(NlogN)。

    2、再然后想到的解法是对数组中的这些元素进行个数统计,但是无论用array还是map进行统计,都要消耗额外的空间,使得空间复杂度提升为O(NlogN)

    3、但是我们肯定需要遍历所有的数字,然后要记得这些数字有没有出现过,或者出现几次。所以我们只能在原数组上进行操作。

    4、这时注意到题目中有一个条件,1 ≤ a[i] ≤ n,也就是数组中的所有元素均在[1, n]之间,题目中也并未说不能改变原数组,所以我们可以利用这一点,结合第2条分析,来解这题。

    5、所以我们就可以遍历数组,以a[i]作为下标来索引a[ a[i] ],因为元素的大小在[1, n]之间,所以不会下标越界。然后将a[ a[i] ]乘以-1,以记录a[i]被我们访问过,当下次我们再索引到a[ a[i] ]时,发现a[ a[i] ]为负数,就说明a[i]被我们访问过,即a[i]出现了两次,此时就把abs( a[i] )添加到返回的结果集中即可。

    6、这里要注意的是,获取下标Index时,要取绝对值然后减1,以对应数组下标从0开始的特性,即index = abs( a[i] ) - 1。

    最后AC代码如下:

    

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        unsigned int length = nums.size();
        unsigned int i;
        int index;
        vector<int> result;
        
        for(i = 0; i < length; ++i)
        {
            index = abs(nums[i]) - 1;
            if(nums[index] < 0)
                result.push_back(abs(nums[i]));
            else
                nums[index] = -1 * nums[index];
        }
        return result;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值