目录

leetcode-数组-双指针

leetcode-数组-双指针

主要分为两种情况(1)快慢指针(2)背向、对向指针-> <-

126.删除有序数组中的重复项

相关标签

相关企业

提示

给你一个 非严格递增排列 的数组 nums ,请你 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。 nums 的其余元素与 nums 的大小不重要。
  • 返回 k

判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}

如果所有断言都通过,那么您的题解将被 通过

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]

示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]

提示:

  • 1 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • nums 已按 非严格递增 排列

解题思路

使用 双指针法 ,慢指针 i 用于记录无重复元素的位置,快指针 j 遍历整个数组。

代码实现

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    if (nums.length === 0) return nums; // 如果数组为空,直接返回

    let i = 0; // 慢指针,指向当前唯一元素的位置
    for (let j = 1; j < nums.length; j++) { // 快指针,遍历数组
        if (nums[j] !== nums[i]) { // 如果发现新元素
            i++; // 慢指针右移
            nums[i]=nums[j];     
        }
    }
    return i+1; // 返回修改后的数组
};

27.移除元素

相关标签

相关企业

提示

给你一个数组 nums

和一个值 val ,你需要 移除所有数值等于 val

的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k ,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。 nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

用户评测:

评测机将使用以下代码测试您的解决方案:

int[] nums = [...]; // 输入数组
int val = ...; // 要移除的值
int[] expectedNums = [...]; // 长度正确的预期答案。
                            // 它以不等于 val 的值排序。

int k = removeElement(nums, val); // 调用你的实现

assert k == expectedNums.length;
sort(nums, 0, k); // 排序 nums 的前 k 个元素
for (int i = 0; i < actualLength; i++) {
    assert nums[i] == expectedNums[i];
}

如果所有的断言都通过,你的解决方案将会 通过

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,_,_,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

提示:

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

解题思路

慢指针 i :指向当前可以放置不等于 val 的元素的位置。

快指针 j :遍历数组,检查每个元素是否等于 val 。

移动元素 :如果 nums[j] !== val ,则将 nums[j] 放到 nums[i] 的位置,并移动慢指针 i 。

返回结果 :最终 i 的值就是不等于 val 的元素数量。

代码实现

/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let i=0;//慢指针
    for(let j=0;j<nums.length;j++){//快指针
        if(nums[j]!==val){
            nums[i]=nums[j];
            i++;//指针右移
        }
    }
    return i;//返回不等于val的元素数量
};

66.加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储 单个 数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。

示例 2:

输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。

示例 3:

输入:digits = [9]
输出:[1,0]
解释:输入数组表示数字 9。
加 1 得到了 9 + 1 = 10。
因此,结果应该是 [1,0]。

提示:

  • 1 <= digits.length <= 100
  • 0 <= digits[i] <= 9

解题思路

这是模拟加法的过程,和数组无关。

这道题的目标是对一个用数组表示的非负整数加一,并返回结果数组。数组的每个元素表示数字的一位,最高位在数组的首位。

思路: 从最低位开始加一 :从数组的最后一个元素(最低位)开始,逐位加一。 处理进位 :如果某一位加一后变为 10 ,则需要将这一位置为 0 ,并向高位进位。 处理最高位进位 :如果最高位也需要进位(例如 [9,9] 加一后变为 [1,0,0] ),则需要在数组的最前面插入 1

代码实现

/**
 * @param {number[]} digits
 * @return {number[]}
 */
var plusOne = function(digits) {
    for(let i=digits.length-1;i>=0;i--){
        if(digits[i]<9) {
            digits[i]++;
            return digits
        }else{
            digits[i]=0;
        }
    }
    digits.unshift(1);
    return digits;
};

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

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

实现思路

使用 双指针法 :

快慢指针 : 使用一个慢指针 slow 指向当前非零元素的位置。 使用一个快指针 fast 遍历数组。 当 nums[fast] 不为零时,将其赋值给 nums[slow] ,然后 slow++ 。

填充零 : 遍历结束后,将 slow 之后的所有位置填充为零。 这种方法的时间复杂度为 O(n) ,空间复杂度为 O(1) 。

代码实现

var moveZeroes = function(nums) {
    let slow=0;
    // 将非零元素移到前面
    for(let fast=0;fast<nums.length;fast++){
        if(nums[fast]!==0){
            nums[slow]=nums[fast]
            slow++
        }
    }
    // 剩余位置填充为0
    for(let i=slow ;i<nums.length;i++){
        nums[i]=0
    }

};