[27].移除元素

移除元素

 


題目

給你一個數組 nums 和一個值 val,你需要 【原地】 移除所有數值等於 val 的元素,並返回移除後數組的新長度。

不要使用額外的數組空間,你必須僅使用 O(1) 額外空間並 【原地】 修改輸入數組。

元素的順序可以改變。你不需要考慮數組中超出新長度後面的元素。

示例 1:

給定 nums = [3,2,2,3], val = 3,

函數應該返回新的長度 2, 並且 nums 中的前兩個元素均爲 2。

你不需要考慮數組中超出新長度後面的元素。

示例 2:

給定 nums = [0,1,2,2,3,0,4,2], val = 2,

函數應該返回新的長度 5, 並且 nums 中的前五個元素爲 0, 1, 3, 0, 4。

注意這五個元素可爲任意順序。

你不需要考慮數組中超出新長度後面的元素。

說明:

爲什麼返回數值是整數,但輸出的答案是數組呢?

請注意,輸入數組是以「引用」方式傳遞的,這意味着在函數裏修改輸入數組對於調用者是可見的。

你可以想象內部操作如下:

// nums 是以“引用”方式傳遞的。也就是說,不對實參作任何拷貝
int len = removeElement(nums, val);

// 在函數裏修改輸入數組對於調用者是可見的。
// 根據你的函數返回的長度, 它會打印出數組中 該長度範圍內 的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

 


函數原型

C的函數原型:

int removeElement(int* nums, int numsSize, int val){}

 


邊界判斷

int removeElement(int* nums, int numsSize, int val){
     if( nums == NULL || numsSize == 0 )
         return 0;
}

 


算法設計:雙指針

數據結構的、數組的、刪除操作,主要是元素前移如何設計呢?

啊哈,雙指針。

用一個指針遍歷數組,如果元素不等於 val ,那就用另一個指針重新爲數組一一賦值。

int removeElement(int* nums, int numsSize, int val){
    if( nums == NULL || numsSize == 0 )
         return 0;

    int cnt = 0;
    for(int i=0; i<numsSize; i++)
    {
        if( nums[i] != val ){
            nums[cnt] = nums[i];   
            cnt++; 
        }
    } 
    return cnt;
}

雙指針的複雜度:

  • 時間複雜度:Θ(n)\Theta(n)
  • 空間複雜度:Θ(1)\Theta(1)
     

算法設計:特殊情況處理

有種特殊情況:num=[4, 1, 2, 3, 5],val=4num = [4, ~1,~2,~3,~5], val = 4,那所有的元素都得前移 11 位。

這時其實可以直接讓最後一個元素佔第一個元素的位置,避免前移。

int removeElement(int* nums, int numsSize, int val){
     if( nums == NULL || numsSize == 0 )
         return 0;
 
     int i = 0;
     while(i < numsSize ){
		if( nums[i] == val ){
			nums[i] = nums[numsSize-1];    // 讓最後一個元素佔第一個元素的位置
			numsSize --;                   // 最後一個元素已經有替身了,移除最後位置的元素
		}else{
		    i ++;
		}
	}
	return numsSize;
}

類似在一些垃圾回收算法裏,刪除數據,通常不是單個單個的刪除,而是批處理刪除。

在生活中,我們扔東西也不是直接給垃圾回收站,而是先扔進屋裏垃圾桶的垃圾,其實垃圾並沒有真的被扔掉,只有垃圾桶塞滿時,纔會清理垃圾桶,那時候垃圾才真正離開了我們家裏,徹底消失了。

思路:先記錄下已經刪除的數據。每次的刪除操作並不是真正地搬移數據,只是記錄數據已經被刪除。當數組沒有更多空間存儲數據時,我們再觸發執行一次真正的刪除操作,這樣就大大減少了刪除操作導致的數據搬移。

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