双指针主要分为左右指针和快慢指针。

删除有序数组中的重复项-26

  1. 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致
  2. 由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
  3. 将最终结果插入 nums 的前 k 个位置后返回 k
  4. 不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
  5. 判题标准:
  6. 系统会用下面的代码来测试你的题解:
  7. int[] nums = [...]; // 输入数组
  8. int[] expectedNums = [...]; // 长度正确的期望答案
  9. int k = removeDuplicates(nums); // 调用
  10. assert k == expectedNums.length;
  11. for (int i = 0; i < k; i++) {
  12. assert nums[i] == expectedNums[i];
  13. }
  14. 如果所有断言都通过,那么您的题解将被 通过。
  15. 示例 1
  16. 输入:nums = [1,1,2]
  17. 输出:2, nums = [1,2,_]
  18. 解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
  19. 示例 2
  20. 输入:nums = [0,0,1,1,1,2,2,3,3,4]
  21. 输出:5, nums = [0,1,2,3,4]
  22. 解释:函数应该返回新的长度 5 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
  23. 提示:
  24. 0 <= nums.length <= 3 * 104
  25. -104 <= nums[i] <= 104
  26. nums 已按 升序 排列
  27. 来源:力扣(LeetCode
  28. 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
  29. 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

删除排序链表中的重复元素-83

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。



示例 1:


输入:head = [1,1,2]
输出:[1,2]
示例 2:


输入:head = [1,1,2,3,3]
输出:[1,2,3]


提示:

链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

移除元素-27

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。



说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}


示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。


提示:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
使用双指针中的快慢指针,遍历数组,如果当前值等于 val ,则跳过,如果不等于就把当前值赋值给慢指针指向的位置

function removeElement(nums: number[], val: number): number {
  const len = nums.length;
  let j = 0;
  for (let i = 0; i < len; i++) {
    // 如果当前元素和目标元素不等
    if (nums[i] !== val) {
      // 将当前元素赋值给 nums[j]
      nums[j] = nums[i];
      // 将 j 向前移动一步
      j++;
    }
  }
    // 这里没有返回 j + 1,是因为在上面的判断语句中 j 已经加过了
  return j;
};

移动零-283

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。



示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:

输入: nums = [0]
输出: [0]


提示:

1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1


进阶:你能尽量减少完成的操作次数吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
使用快慢指针,将不是零的元素移到前面,慢指针及其后面的值赋值为 0 即可

var moveZeroes = function (nums) {
    let j = 0;
    let len = nums.length;
    for (let i = 0; i < len; i++) {
        if (nums[i] !== 0) {
            nums[j] = nums[i];
            j++;
        }
    }
    for (; j < len; j++) {
        nums[j] = 0
    }
    return nums;
};