文章目录
- 题目简介
- 题目解答
- 解法一:双指针
- 代码:
- 复杂度分析:
- 解法二:双指针优化
- 代码:
- 复杂度分析:
- 题目链接
大家好,我是晓星航。今天为大家带来的是 相关的讲解!😀
题目简介
题目解答
解法一:双指针
代码:
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;
}
}
使用双指针:右指针 right指向当前将要处理的元素,左指针 left指向下一个将要赋值的位置。
那么此时情况就很简单了,之有两种right指向的元素等于val,right指向的元素不等于val。
- 如果右指针指向的元素不等于 val,它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移(left++ right++);
- 如果右指针指向的元素等于 val,它不能在输出数组里,此时左指针不动,右指针右移一位(right++)。
最后题目要求返回移除后数组的新长度,就是left的长度,我们直接返回整型left即可。
复杂度分析:
解法二:双指针优化
这里也是使用的双指针,但是这里效率比第一种解法要高,为什么呢,且听我细细道来。
思路:如果要移除的元素恰好在数组的开头,例如序列[1,2,3,4,5],当 val为 1时,我们需要把每一个元素都左移一位。注意到题目中说:「元素的顺序可以改变」。实际上我们可以直接将最后一个元素 5 移动到序列开头,取代元素 1,得到序列[5,2,3,4],同样满足题目要求。这个优化在序列中 val\textit{val}val 元素的数量较少时非常有效。
代码:
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;
}
}
通过代码分析,我们直接将双指针指向数组的开头和结尾,然后我们使用while进行死循环,直到left>=right跳出,当我们左指针等于要删除的值val时,我们直接将左指针的值指向右指针的值然后右指针减减,继续循环。如果左指针的值不等于val那么左指针就直接加加往右走。直到我们左指针和右指针相遇就跳出循环,此时我们左指针的值就是我们数组的长度大小。
这个方法的好处是我们只需要遍历数组一次就可以解答完成。
复杂度分析:
题目链接
27. 移除元素 - 力扣(LeetCode)
感谢各位读者的阅读,本文章有任何错误都可以在评论区发表你们的意见,我会对文章进行改正的。如果本文章对你有帮助请动一动你们敏捷的小手点一点赞,你的每一次鼓励都是作者创作的动力哦!😘