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,那就把右指针的数付给左指针,右指针向左移动,否则左指针向右移动。
这个太巧妙了,我怎么就没想到