每臨大事有靜氣,不信今時無古賢
1. 題目
給你一個數組 nums 和一個值 val,你需要 原地移除所有數值等於 val 的元素,並返回移除後數組的新長度。
這道題與 LeeCode 26 - daily03同屬於數組 類型的題目。且在解法上也存在相同之處。
本題筆者也採用 雙指針套路
2. 解法
注意 原地,往往意味着:拷貝覆蓋
2.1 過程講解
示例:nums = [3,2,2,3] value = 3
- low = 0 ; fast = 0; 結果:nums = [3,2,2,3] ,low = 0; fast = 1;
- low = 0 ; fast = 1 ; 結果:nums = [2,2,2,3] , low = 1; fast = 2;
- low = 1 ; fast = 2 ; 結果: nums = [2,2,2,3],low = 2 ; fast = 3;
- low = 2; fast = 3; 結果:nums = [2,2,2,3], low =2 ; fast = 4;
- 條件結束,返回low = 2;
詳細步驟:請參考這裏
2.2 不堪代碼
public int removeElement(int[] nums, int val) {
// 處理邊界條件
if(nums == null || nums.length == 0) return 0;
// 快慢指針
int low = 0;
// 需要特別強調的是,此處的快指針也是從0開始,WHY ?
int fast = 0;
while(fast < nums.length){
if(val == nums[fast]){
// 1.只更新快指針
fast ++;
}else{
// 原地:拷貝覆蓋
nums[low] = nums[fast];
// 2. 快慢指針同時進步
low ++;
fast ++;
}
}
return low;
}
3. 技巧
遇見此類型題,高手直接都採用快慢指針。但是吾等菜鳥,還是需要稍思片刻…
一般而言,慢指針大部分都是從起始位置開始的(數組自然是從下標爲0);
But快指針的設置還是有些技巧的。大部分情況下,既然是快指針,那自然是比慢指針要快一些,但也需要視情況而定。
3.1 快指針的設置要謹慎
要考慮情況,設定快指針。
以此題來展開論述:快慢指針是同時起步的。Why ?
因爲數組的第一個值可能等於給定的值value. nums = [2], value = 2
3.2 快慢指針的步調問題
當使用快慢指針套路輕車熟路時,會發現這個套路是有規律可循的。
- 往往是在一種情況下,只更新快指針;
- 另一種情況下,快慢指針同時要求進步;
大家可以仔細揣摩一下
另外,做算法題筆紙隨手把代碼的過程給走一遍,會有很大幫助。