經典快慢指針————leetcode第26題

題目如下(出自leetcode第26題):
給定一個排序數組,你需要在 原地 刪除重複出現的元素,使得每個元素只出現一次,返回移除後數組的新長度。

不要使用額外的數組空間,你必須在 原地 修改輸入數組 並在使用 O(1) 額外空間的條件下完成。

示例 1:
給定數組 nums = [1,1,2],
函數應該返回新的長度 2, 並且原數組 nums 的前兩個元素被修改爲 1, 2。
你不需要考慮數組中超出新長度後面的元素。

示例 2:
給定 nums = [0,0,1,1,1,2,2,3,3,4],
函數應該返回新的長度 5, 並且原數組 nums 的前五個元素被修改爲 0, 1, 2, 3, 4。
你不需要考慮數組中超出新長度後面的元素。

說明:

爲什麼返回數值是整數,但輸出的答案是數組呢?
請注意,輸入數組是以「引用」方式傳遞的,這意味着在函數裏修改輸入數組對於調用者是可見的。
你可以想象內部操作如下:

// nums 是以“引用”方式傳遞的。也就是說,不對實參做任何拷貝
int len = removeDuplicates(nums);
// 在函數裏修改輸入數組對於調用者是可見的。
// 根據你的函數返回的長度, 它會打印出數組中該長度範圍內的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

解:
題幹中的條件很多,我們先來看一下,首先是一個排序數組,第二點是要求原地刪除,第三點是可以使用O(1)的額外空間,後面一段文字的具體意思是題目傳入的nums是以引用(數組頭地址)形式傳入,當函數結束時我們需要返回的是已經沒有重複元素的一個數組nums,這道題的解法可以直接暴力法三循環來做,實際上這樣做的時間複雜度非常高,爲O(n3),所以我們需要尋找更高效的辦法,我的另一篇博客中有寫到雙指針的一個用法,點擊這裏查看,這道題可以使用雙指針來將問題簡單化,雙指針實際上是一個快指針和一個慢指針組成的,快指針每循環一次就移動一次,慢指針只有當特定條件下才會移動,此題中快指針的作用是遍歷數組,訪問所有元素,慢指針作用是賦值。
代碼如下所示:


int removeDuplicates(int* nums, int numsSize) {
    //快指針爲b,a爲慢指針
	int a, b;
    //數組沒有元素存在,直接返回0和數組本身
	if (numsSize == 0)
		return numsSize;
	for (a = 0, b = 1;b < numsSize;b++)
	{
		if (nums[a] != nums[b])
		{
			nums[++a] = nums[b];
		}
	}
	//a從0開始實際上爲下標,所以最後返回需要+1
	return (a + 1);
}

That’s All.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章