LeetCode27. 移除元素题解
LeetCode27. 移除元素题解
题目链接:
https://leetcode.cn/problems/remove-element/
题目描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例:
输入:nums = [3,2,3,3,3,3,3,3,3,2], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3,3,3,3,3,3,3] 或 nums = [2,2,0,0,0,0,0,0,0,0],也会被视作正确答案。
思路
以题目给出的示例而言,我们可以把数组分为两个部分:
前一部分是不为3的;
后一部分是等于3的,也就是该删除的。
我们可以定义快慢指针:
![快慢指针的定义](./2.LeetCode27. 移除元素题解.assets/image-20240506200456828.png)
[0,slow-1]代表值不为3的区域;
[slow,fast-1]代表值为3的区域;
[fast,n-1]代表未处理的区域。
循环逻辑
- 初始化快慢指针slow,fast,均初始化为0,让它们都为数组开头下标;
- 如果nums[fast] 不等于 val,那么就交换 nums[fast] 和 nums[slow],并把slow指针向后移动;
- fast指针向后移动
直到fast超出数组长度。
然后返回slow的值,就是所求数组长度。
代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0, fast = 0;
while(fast < nums.length){
if(nums[fast] != val){
swapNumsVal(nums,slow,fast);
slow++;
}
fast++;
}
return slow;
}
private void swapNumsVal(int[] nums, int slow, int fast) {
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
}
}
注意
题目中说:
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素
实际上就是把前部分视为未被删除的元素,且不考虑顺序;后半部分是什么元素都可以。
那我们就不需要进行交换了。
修改后的代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0, fast = 0;
while(fast < nums.length){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
private void swapNumsVal(int[] nums, int slow, int fast) {
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
}
}