[LeetCode] 442. Find All Duplicates in an Array

題目鏈接: https://leetcode.com/problems/find-all-duplicates-in-an-array/description/

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]

解題思路

題意爲找出數組中出現兩次的元素,有兩種思路。

1. 對應位置取負數
因爲數組大小爲 n,每個元素 nums[i] 都在 [1, n] 範圍內,因此可以讓每個下標對應範圍內的一個數,由於下標從 0 開始,所以下標 i 對應數字 i + 1

遍歷數組的每個元素 nums[i],檢查 nums[abs(nums[i]) - 1],若爲正數,則第一次遇到值爲 nums[i] 的元素,將下標爲 abs(nums[i]) - 1 的元素取負數,用以表示已經有了 nums[i] 這個數;若爲負數,則表示之前已經有值爲 abs(nums[i]) 的元素,將該值添加到返回數組。

2. 交換元素至正確位置
遍歷數組的每個元素 nums[i],將 nums[i] 與其正確位置的數 nums[nums[i] - 1] 交換,直至 nums[i] == nums[nums[i] - 1]。此時要麼 i == nums[i] - 1,爲同一個元素;要麼 i != nums[i] - 1,爲兩個相同值的不同元素,暫時不添加到返回數組,要不可能會出現重複。

待第一次遍歷完後,進行第二次遍歷,將與位置不對應的數添加到返回數組中,即爲結果。

Code

1. 對應位置取負數

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res;

        for (int i = 0; i < nums.size(); ++i) {
            if (nums[abs(nums[i]) - 1] < 0) {
                res.push_back(abs(nums[i]));
            } else {
                nums[abs(nums[i]) - 1] *= -1;
            }
        }

        return res;
    }
};

2. 交換元素至正確位置

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res;

        for (int i = 0; i < nums.size(); ++i) {
            while (nums[i] != nums[nums[i] - 1]) {
                int tmp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = tmp;
            }
        }

        for (int i = 0; i < nums.size(); ++i) {
            if (i + 1 != nums[i]) res.push_back(nums[i]);
        }

        return res;
    }
};
發佈了60 篇原創文章 · 獲贊 18 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章