leetcode刷题打卡

  1. 移除元素
    给你一个数组 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,3,0,4]
    解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
    提示:
    0 <= nums.length <= 100
    0 <= nums[i] <= 50
    0 <= val <= 100
    提示 1
    The problem statement clearly asks us to modify the array in-place and it also says that the element beyond the new length of the array can be anything. Given an element, we need to remove all the occurrences of it from the array. We don’t technically need to remove that element per-say, right?
    提示 2
    We can move all the occurrences of this element to the end of the array. Use two pointers!
    提示 3
    Yet another direction of thought is to consider the elements to be removed as non-existent. In a single pass, if we keep copying the visible elements in-place, that should also solve this problem for us.

解题思路

在 Java 中,要实现原地移除数组中所有等于 val 的元素,并返回新数组的长度,可以使用双指针技术。有两种双指针的方法:一种是快慢指针,另一种是双向指针。这里使用快慢指针的方法,因为它更直观且易于理解。快慢指针方法的核心思想是用两个指针在一次遍历中完成任务,其中:

  • 慢指针(slow):标记了处理后数组的末尾,即下一个不等于 val 的元素应该放置的位置。
  • 快指针(fast):用于遍历原数组,查找不等于 val 的元素。

遍历过程中,当快指针指向的元素不等于 val 时,将其复制到慢指针的位置,然后慢指针和快指针同时向前移动。如果快指针指向的元素等于 val,则快指针向前移动,而慢指针保持不动。这样,所有不等于 val 的元素都会被复制到数组的前部,而等于 val 的元素被跳过,从而实现了原地修改数组。

代码实现

public int removeElement(int[] nums, int val) {
    int slow = 0; // 初始化慢指针
    for (int fast = 0; fast < nums.length; fast++) {
        // 当快指针指向的元素不等于val时,复制到慢指针的位置
        if (nums[fast] != val) {
            nums[slow] = nums[fast];
            slow++; // 慢指针向前移动
        }
        // 如果等于val,快指针向前移动,慢指针不动
    }
    return slow; // 慢指针的位置即为新数组的长度
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。快指针负责遍历整个数组,因此时间复杂度为 O(n)。
  • 空间复杂度:O(1)。除了输入数组外,只使用了常数级别的额外空间(快慢指针)。

总结

通过使用快慢指针的方法,可以有效地在一次遍历中原地移除数组中所有等于给定值 val 的元素。这种方法不仅满足了题目对空间复杂度的要求,而且实现起来简单高效。此外,这种双指针技术在解决数组和链表相关问题时非常有用,是一种值得掌握的通用技巧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值