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