領釦網演算法學習筆記 -- 27
阿新 • • 發佈:2018-11-24
領釦網演算法學習筆記
本系列的演算法題目來自領釦網
陣列類演算法第二天
題目:
給定一個數組 *nums *和一個值 val,你需要原地移除所有數值等於 *val *的元素,返回移除後陣列的新長度。
不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 O(1) 額外空間的條件下完成。
元素的順序可以改變。你不需要考慮陣列中超出新長度後面的元素。
示例:
給定 nums = [3,2,2,3], val = 3, 函式應該返回新的長度 2, 並且 nums 中的前兩個元素均為 2。 給定 nums = [0,1,2,2,3,0,4,2], val = 2, 函式應該返回新的長度 5, 並且 nums 中的前五個元素為 0, 1, 3, 0, 4。
解題思路:
思路一:
按照上一篇的思路,第一感覺就是,定義一個變數,初始值為0,然後判斷,如果不為指定值則將值賦給以該變數作為位置的陣列值,然後該變數+1,最後新陣列的長度就是該變數的值。
class Solution {
public int removeElement(int[] nums, int val) {
int nonValIndex = 0;
for(int i=0;i<nums.length;i++){
if(nums[i] != val){
nums[nonZeroIndex++ ]=nums[i];
}
}
return nonValIndex;
}
}
// 用時9ms左右
後續思考:
這解題思路和5ms的思路一致,只是把自增放到了賦值裡面就這樣了,以後要把自增從賦值語句中拿出來。
領釦上面該題其他高質量範例:
class Solution {
public int removeElement(int[] nums, int val) {
int begin = 0;
if (nums.length == 0) {
return 0;
} else if (nums.length == 1) {
if (nums[0] == val) {
return 0;
} else {
return 1;
}
}
int end = nums.length - 1;
while (begin < end) {
//找到目前第一個值為val的元素
while (nums[begin] != val && begin < end) {
begin++;
}
//從後面找到第一個值不為val的元素
while (nums[end] == val && begin < end) {
end--;
}
if (begin != end) {
int tmp = nums[begin];
nums[begin] = nums[end];
nums[end] = tmp;
} else {
if (nums[begin] != nums[end]){
return end + 1;
}else{
if(nums[end] == val){
return end;
}
return end + 1;
}
}
}
return end;
}
}
// 用時6ms
自我整理:
這部分程式碼思路我沒有想到,且這部分程式碼有一個我很喜歡的點,也是我目前欠缺的點,就是在執行程式碼前對條件進行判斷,避免出現了因為條件根本就不滿足直接導致迴圈主要程式碼執行出現異常。
這題的思路如下:
- 將從頭開始遍歷得到的第一個指定值的位置 與 從尾反向遍歷得到第一個不是指定值的位置的值進行交換,直到陣列全部遍歷完。
- 這樣得到的陣列前面部分是非指定值,後面部分是指定值,
- 新陣列的長度就是前面部分的長度。
自我總結:
平時一定要養成良好的習慣,編寫程式碼時,要對傳入的引數進行資料的判斷,避免因傳入的資料錯誤,或者是空值導致出現程式異常或者Bug。判斷的同時就可以實現解決方法。