LeetCode题解 week11

来源:互联网 发布:淘宝流量是怎么计算的 编辑:程序博客网 时间:2024/05/23 00:02

T442. Find All Duplicates in an Array
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]

关于这道题,我想到的一个办法是使用map,map查找只需要O(Log N)的复杂度,之后按顺序,对输入中的每个数进行一次查找,如果没找到,就把这个数放进map中,若是找到了,那就说明这个数是重复的,把这个数放入输出中。
参考代码如下:

class Solution {public:    vector<int> findDuplicates(vector<int>& nums) {        vector<int> result;        if(nums.size() == 0)            return result;        unordered_map<int, int> nums_map;        nums_map[nums[0]] = 0;        for(int i = 1; i < nums.size(); i++) {            if(nums_map.find(nums[i]) == nums_map.end())                nums_map[nums[i]] = i;            else                result.push_back(nums[i]);        }        return result;    }};

但是,这个方法会使用到额外的空间,而且会导致O(N Log N)的时间复杂度,并不是最优解。

此时我们注意到,输入的数的范围在[1, n]之间,且重复的数只出现2次,所以我们可以使用标记法。由于数组下标为[0, n-1],所以我们要对输入的值减一。对输入的每一个数(input[i]),我们可以映射到input[input[i]-1],之后将input[input[i]-1]的值设为负数,相同的数会映射到input的相同位置,也就是说,当我们发现映射到的input[input[i]-1]为一个负数的时候,便说明这个数已经出现过一次,是重复的数,将其放入到output即可,同时也达成了无额外空间利用以及O(N)的时间复杂度。

参考代码如下:

class Solution {public:    vector<int> findDuplicates(vector<int>& nums) {        vector<int> result;        for(int i = 0; i < nums.size(); i++) {            int index = abs(nums[i]) - 1;            if(nums[index] < 0)                result.push_back(index+1);            nums[index] = -nums[index];        }        return result;    }};
原创粉丝点击