题目
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。将最终结果插入 nums 的前 k 个位置后返回 k 。不使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。
从判断方式可以看出,是输入已知的期望答案,将函数调用后的数组与已知答案进行比较是否匹配,且是在原地修改数组,所以函数只需要返回修改后的长度即可
思路
若是没有要求原地修改的话,最简单的思路就是暴力遍历,每经过一个不重复的值就赋到新的数组上,由于原地修改的要求,则用到指针。
且为双指针,一个指针(快指针)负责向下走也就是遍历,另一个指针(慢指针)则指向下一个填充的位置,当快指针指向一个与上一个元素不同的数时,将它填充到慢指针所指向的位置即可。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n=nums.size();
if(n==0)
{
return 0;
}
int fast=1,slow=1;
while(fast<n)
{
if(nums[fast]!=nums[fast-1])
{
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
没有什么需要新学的概念,掌握好双指针的思想就好。。三天做一道题,觉越来越多,好懒。。
补 理解了双指针的思想解决27题就很简单了
题干也对主函数中函数的调用解释了(虽然很明显。。)
按照26的思路直接可码
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow=0,fast=0;
int n=nums.size();
while(fast<n)
{
if(nums[fast]!=val)
{
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
题解里还有另一种方法
仍然是双指针,但是一个在最左一个在最右,当左指针指向的数为val时,将右指针所指的数赋给左指针所指的,继续判断,知道两指针相遇。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left = 0, right = nums.size();
while (left < right) {
if (nums[left] == val) {
nums[left] = nums[right - 1];
right--;
} else {
left++;
}
}
return left;
}
};
载请注明出处。
嗯。。
本文介绍了一种使用双指针技术解决数组中重复元素问题的方法。通过快慢两个指针配合,实现原地删除数组中的重复元素或特定值,同时保持元素顺序不变。文章提供了两种双指针解决方案,并附带示例代码。
1454

被折叠的 条评论
为什么被折叠?



