移除數組中的指定值
Input:數組nums,需要移除的元素val
Output:原數組nums以及移除val後的數組長度
這是LeetCode上難度爲簡單的題,最近做的時候,首先想的方法就是,判斷當前有多少個連續的值均爲val,然後把後面的元素全部前移,如下所示。
public int removeElement(int[] nums, int val) {
//首先判斷數組是否爲空
if(nums == null || nums.length == 0) return 0;
int count = 0;
for(int i = 0;i<nums.length;i++){
if(nums[i] == val){
int bias = 0;
for(int j = i;j<nums.length;j++){
if(nums[j] != val) break;
bias++;
}
shiftLeft(nums, i, bias, val);
}
}
//此時數組後部分全爲元素val,需要遍歷一次然後計數
for(;count<nums.length;count++){
if(nums[count] == val) break;
}
return count;
}
/* 將start+bias開始的值全部前移bias個位置*/
private void shiftLeft(int[] nums, int start, int bias, int val){
for(int i = start+bias;i<nums.length;i++){
nums[i-bias] = nums[i];
//表明該位置的值無效,所以重新賦值爲val
nums[i] = val;
}
}
然後一提交發現自己10個月前已經做過了! = _ =,而且當時使用的是一個雙指針,代碼更加通俗易懂,和官方解答是一樣的。平常還是得多學習總結,繼續努力才行,唉。。。
(僅遍歷一次,時間複雜度爲O(n),空間複雜度爲O(1))
public int removeElement(int[] nums, int val) {
if(nums == null || nums.length == 0) return 0;
//記錄當前元素個數
int count = 0;
for(int i = count;i<nums.length;i++){
if(nums[i] != val){
nums[count++] = nums[i];
}
}
return count;
}
然後是又刷了一道類似的題,需要移除數組中重複的元素,也就是每個元素只保留一次
Input:數組nums
Output:原數組nums以及移除val後的數組長度
仍然是雙指針的思路,相比於前一題,這次不是往後移一個位置就行了,而是平移至另一個不等的元素,所以使用了一個while循環代替了原來的i++。
public int removeDuplicates(int[] nums) {
//count記錄當前元素個數
int count = 0;
for(int i = count;i<nums.length;){
int val = nums[i];
nums[count++] = val;
while(i < nums.length){
if(nums[i] != val){
break;
}
i++;
}
}
return count;
}