1 描述
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
我自己的理解是: 比如给一个数组是[2,2,3,1] val是2,那么数组就要变为[1,3,x,x],返回2 这里x,x表示任意数,只有不等于val就行,返回2表示该数组有2个数不等于val。还有比如数组是[3,3]val是3 ,那么数组就变为了[x,x] 返回0,这里0就表示数组有0个不等于val的。具体解释可以详见LeetCode官网,这里我按照我自己解释可以做出来题目。
2 思路:
思路:
- 用一个左右指针 left 和 right 分别指向数组第一个和最后一个
- 在while循环遍历, 先进行right位置一直向左判断,寻找right上不为val的元素,若为val的元素,则用一个不是val的元素替换
- 然后对left向右判断,若找到val的元素,则它与right元素的值进行交换,交换后将right的值赋一个不为val的值,然后同时向里移动
- 然后对left向右判断,若找到val的元素,则它与right元素的值进行交换,交换后将right的值赋一个不为val的值,然后同时向里移动
- 最后返回right位置上元素的数量即++right,因为最终left会超过right,因此right指向的就是最后一个不等于val的元素的位置
Java代码
public class Solution {
/*
* 思路:用一个左右指针 left 和 right 分别指向数组第一个和最后一个
* 在while循环遍历, 先进行right位置一直向左判断,寻找right上不为val的元素,若为val的元素,则用一个不是val的元素替换
* 然后对left向右判断,若找到val的元素,则它与right元素的值进行交换,交换后将right的值赋一个不为val的值,然后同时向里移动
* 若没找到等于val的元素,则left向右移动,准备下一次while循环
* 最后返回right位置上元素的数量即++right,因为最终left会超过right,因此right指向的就是最后一个不等于val的元素的位置
* */
public static int removeElement(int[] nums, int val) {
int replace = -1;
int left = 0;
int right = nums.length - 1;
while (left <= right) {
//先找到右边第一个不为val的元素,同时 right的值不能小于left
while (right >= left && (nums[right] == val)) {
nums[right] = replace;
right--;
}
//若发现了right跑到了left的左边,则表示right就代表了最后一个不为val的元素,那么直接返回right位置元素的数量即++right
if (right <= left) {
return ++right;
}
//在right找到右边不为val的元素后,开始从left开始寻找
//若找到val则与right的元素交换,交换后并将right的值赋一个不为val的,这里用-1代替
//然后right向左移动,left向移动,进行下一个while循环
//若当前位置的值不等于val,那么left向左移动。进行下一次while循环
if (nums[left] == val) {
nums[left] = nums[right];
nums[right] = replace;
right--;
left++;
} else {
left++;
}
}
return ++right;
}
}