forked from wisdompeak/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4ea888e
commit 85a8019
Showing
1 changed file
with
6 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,15 @@ | ||
### 442.Find-All-Duplicates-in-an-Array | ||
|
||
#### 解法1 | ||
此题和 041.First-Missing-Positive 的解法非常相似。题目的共同点是:数组的元素规定了是从1\~N. 这就强烈暗示了,如果试图把正整数1~N顺次放入nums[0]~nums[N-1]中,那么没有被正确归位的那个元素(即nums[i]!=i+1)一定有“问题”。 | ||
|
||
对于“把正整数1~N顺次放入nums[0]~nums[N-1]中”的这种特殊的排序任务,有如下典型的时间复杂度o(n)、空间复杂度o(1)的方法: | ||
|
||
遍历所有元素nums[i],发现如果nums[i]!=i+1时,说明当前的nums[i]这个数没有被放置在合适的顺序位置。于是交换nums[i]和nums[nums[i]-1]。这样做的结果是:把nums[i]放到了它应该在的位置(正确归位),同时nums[i]有了新的值,需要再重复判断、交换的过程。这样的步骤持续到 nums[i]==nums[nums[i]-1],这样就到了一个死循环,对于i这个位置就不能再做任何操作,于是跳过。 | ||
|
||
等到所有元素都遍历结束,那么所有元素就会被“力所能及”地归入了它们应该在的顺序位置。那么此时,对于那些nums[i]!=i+1的、没有正确归位的元素,在本题的题意下,就是那些重复的元素,可以轻易地挑出来。 | ||
|
||
#### 解法2 | ||
还有一种比较花哨的解法。对于数值x,我们如何不通过extra space来记录它是否出现过呢?方法是将nums[x]上的数字变成负数来进行标记,注意我们并不关心nums[x]是多少。只关心nums[x]是负数时表示x曾经出现过,反之表示x还没出现过。 | ||
|
||
所以我们依次遍历数组里的每个数字abs(x),注意我们关心数值时必须看的是abs(x),因为x的符号可能被encode了其他含义(如上所说)。如果nums[abs[x]]<0,表示abs(x)曾经出现过,加入我们的答案中。反之,说明abs(x)第一次出现,所以我们将nums[abs(x)]标记为负数,以此留下这个标记。 |