88.合并兩個有序數組
- 1 題目介紹
- 1 個人解題思路
- 1.1 解題代碼
- 1.2 思路解析
- 2、分析官方題解
- 2.1 單側雙指針
- 2.2 雙側雙指針
1 題目介紹
給你一個數組 nums 和一個值 val,你需要 原地 移除所有數值等于 val 的元素,并返回移除后數組的新長度。
不要使用額外的數組空間,你必須僅使用 O(1) 額外空間并 原地 修改輸入數組。
元素的順序可以改變。你不需要考慮數組中超出新長度后面的元素。
1 個人解題思路
1.1 解題代碼
class Solution {public int removeElement(int[] nums, int val) {int not_val_nums=0;if(nums.length==0){return nums.length;}for(int i=0;i<nums.length;i++){if(nums[i]!=val){not_val_nums++;}}int length=0;int def_length=nums.length;while(length<def_length){if(nums[length]==val){for(int j=length;j<nums.length-1;j++){nums[j]=nums[j+1];}def_length--;}else{length++;if(length==not_val_nums){break;}}}return length;}
}
1.2 思路解析
- 首先遍歷一遍,統計不等于val的數的個數not_val_nums
- 然后開始遍歷,如果等于val,那么就把每個之后的數付給前面的數。然后因為覆蓋了一個數,也就是移除了一個數,那么實際上數組的長度是減一的。
- 如果不等于val,那就往后走。直到走到等于最開始統計的數not_val_nums退出
2、分析官方題解
2.1 單側雙指針
class Solution {public int removeElement(int[] nums, int val) {int n = nums.length;int left = 0;for (int right = 0; right < n; right++) {if (nums[right] != val) {nums[left] = nums[right];left++;}}return left;}
}
指針都在同一側,如果右指針負責遍歷,左指針交換,如果右指針等于val,就跳過,如果不等于val,那就把右指針的數移到左指針,然后左指針++,等待下一次交換。
挺巧妙地,我本來也想寫成這個的,奈何腦子沒轉過來。
2.2 雙側雙指針
class Solution {public int removeElement(int[] nums, int val) {int left = 0;int right = nums.length;while (left < right) {if (nums[left] == val) {nums[left] = nums[right - 1];right--;} else {left++;}}return left;}
}
這個我一看名字我就知道怎么解了,左右各一個指針,如果左指針等于val,那就把右指針的數付給左指針,右指針向左移動,否則左指針向右移動。
這個太巧妙了,我怎么就沒想到