這道題要我們從有序數組中去除重複項,題目難度雖然被歸為 easy 等級,但在條件限制上的討論,蠻多東西可以釐清討論的。 英文方面寫得蠻長,記得要看到最後因為有寫一些限制如 :

  • O(1) extra memory
  • The relative order of the elements should be kept the same.

所以不能用 Set 或另開 array 去寫。另外也花了些篇幅去說明,只要原 array 前面長度部分內,有把所有不重複數字列出來就好,不需要在意後面 array 的元素和 array 的長度。


兩個重點條件限制 :

  • O(1) extra memory

  • The relative order of the elements should be kept the same.

以下使用各種方式來解題,當作練習

思路

使用快慢指針來遍歷 array :

  • lowerfaster 都從 index 0 開始
  • lower之前的 index 都是處理好的數字

接下來開始循環邏輯 :

  • faster == 0 ,則為初始狀態,快慢指針都前進。

  • 因為定義 lower 之前的 index 均為處理好的資料,故若條件 nums[lower - 1 ] != nums[faster] ,則 快慢指針都前進,並把 nums[lower] 換成 nums[faster]

很自然的,可以把 faster == 0nums[lower - 1 ] != nums[faster] 條件併在一起。因為初始狀態 :

  • faster = 0
  • lower = 0

這樣 nums[lower] = nums[faster] 改動其實等於沒改。


解答

class Solution {
	public int removeDuplicates( int[] nums ) {
		int faster = 0;
		int lower = 0;
		while (faster < nums.length) {
			if ( faster == 0 || nums[lower - 1] != nums[faster] ) {
				nums[lower++] = nums[faster++];
			} else {
				faster++;
			}
		}
		return lower;
	}
}

nums[lower++] = nums[faster++]; 是個蠻簡潔不錯的寫法,可以在賦值完之後,才再讓指針前進。想提醒自己這個部分,才特別註記筆記這題的。

思考了一下,這題的條件 :

  • The relative order of the elements should be kept the same.

好像沒有用,因為雙指針的題型,會改變 order 的是反向指針,這題應該不能用反向指針去解題…


其它思路

一樣是使用快慢指針來遍歷 array ,最開始時兩個指針都指向第一個數字,但

  • 兩個指針指的數字相同,則快指針向前走一步
  • 如果不同,則慢指針先向前一步,把慢指針對應 index 數字換成快指針對應 index 數字,再來快指針前進

可以發現這樣的邏輯下,慢指針的位置,就代表目前置換過的 index 。當快指針走完整個數組時,慢指針當前位置,就代表最後更新的位置,故 lower + 1 就是數組中不同數字的個數。

解答

class Solution {
	public int removeDuplicates( int[] nums ) {
		int faster = 0;
		int lower = 0;
		while (faster < nums.length) {
			if ( nums[lower] == nums[faster] ) {
				++faster;
			} else {
				nums[++lower] = nums[faster++];
			}
		}
		return lower + 1;
	}
}

上面邏輯也可以換成 for loop 也可以解 !

class Solution {
	public int removeDuplicates( int[] nums ) {
		int lower = 0;
		for ( int faster = 0; faster < nums.length; faster++ ) {
			if ( nums[faster] != nums[lower] ) {
				nums[++lower] = nums[faster];
			}
		}

		return lower + 1;
	}
}

時間空間複雜度

時間複雜度: O(N)

遍歷 nums 需 O(N)

空間複雜度:O(1)

因為禁止開額外空間,此題強制 O(1)


Vocabulary

In-place

特殊片語,代表直接對輸入的 data-structure 進行操作,不能另開額外空間。

in-place algorithm 會應用在一些不希望大量增加記憶體使用量,是拿時間換取空間的概念。


參考資料