Description
給你一個數組 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。
注意這五個元素可為任意順序蚕冬。
你不需要考慮數組中超出新長度后面的元素免猾。
Analyze
給定的函數如下:
- @param nums 一個整數數組
- @param numsSize 數組長度
- @param val 要移除的元素
- @return 移除后的數組長度
此題在題目中隱含了一個條件,不過在示例中體現了囤热,就是題中只是說返回刪除后的數組長度猎提,但實際上返回的長度 n 在原數組的前 n 項是不能出現目標元素的,即并不能僅僅返回一個長度旁蔼,還要把數組的內容修改成符合的值锨苏。
這題可以這么考慮,采用雙指針從頭開始遍歷數組棺聊,一旦發(fā)現要刪除的元素蚓炬,保留一個指針,另一個指針繼續(xù)向下遍歷躺屁,直到找到一個非目標元素肯夏,此時直接把前面保留的目標元素覆蓋,同時犀暑,兩個指針之間的元素也要一個一個全部由非目標值覆蓋驯击,直到有一個指針遍歷完數組∧涂鳎可以參考如下例子:
示例2中給定 nums = [0,1,2,2,3,0,4,2]徊都,val = 2,此時 pre 和 last 同時指向 0广辰,0 不是目標元素暇矫,兩指針同時往右移動直到 2,此時 pre 和 last 都指向 2 這個目標元素择吊,因此 last 留下李根,pre 繼續(xù)往前尋找可以覆蓋 2 的元素,pre 往右移動 1發(fā)現其指向的還是 2几睛,繼續(xù)往右移動 1房轿,此時指向3這個非目標元素,因此用 pre 指向的 3 覆蓋 last 指向的 2 所森,然后 pre 和 last 同時右移囱持,這時 last 和 pre 之間的值都是可以舍棄的值了(因為他們之間要么是目標元素,要么是已經用來覆蓋目標元素了)焕济,這樣循環(huán)直到遍歷完全纷妆,最后數組會變成這樣:[0,1晴弃,3掩幢,0逊拍,4,0粒蜈,4,2] 旗国,此時返回 last 所指向的下標就可以了枯怖。
Realization
- 判斷
如果 i 指向的不是目標元素就覆蓋 j 指向的元素(這里沒有判斷 j 指向的是不是目標元素,因為如果 j 指向的是目標元素就得覆蓋能曾,如果不是的話相當于 i 和 j 都指向同一個值度硝,也就不存在覆蓋了)
-
提交
Dictionary
雙指針或者說快慢指針這種方法在LeetCode中用的十分頻繁,因此掌握好雙指針的用法不僅可以提高解題效率寿冕,對代碼的效率也有很大的提高蕊程。
附源代碼
int removeElement(int* nums, int numsSize, int val){
int i = 0, j = 0;
for(i = 0; i < numsSize; i++)
{
if(nums[i] != val)
{
nums[j++] = nums[i];
}
}
return j;
}