【Leetcode每日一题】27. 原地移除元素|神级理解双指针

勤奋不是嘴上说说而已,而是实际的行动,在勤奋的苦度中持之以恒,永不退却。业精于勤,荒于嬉;行成于思,毁于随。在人生的仕途上,我们毫不迟疑地选择勤奋,她是几乎于世界上一切成就的催产婆。只要我们拥着勤奋去思考,拥着勤奋的手去耕耘,用抱勤奋的心去对待工作,浪迹红尘而坚韧不拔,那么,我们的生命就会绽放火花,让人生的时光更加的闪亮而精彩。

导读:本篇文章讲解 【Leetcode每日一题】27. 原地移除元素|神级理解双指针,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在这里插入图片描述

在这里插入图片描述

题目描述

链接: 27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

Given an integer array nums and an integer val, remove all occurrences of val in nums in-place. The relative order of the elements may be changed.
Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.
Return k after placing the final result in the first k slots of nums.
Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.

题目分析:

  • 题型:一维数组原地移除元素
  • 关键:双指针法
    • 【指针1号】:从数组头开始遍历,查找
    • 【指针2号】:从数组头开始,控制数组不出现target。
      这个指针坚持被叫作慢指针,是因为走的慢(但是关键是理解好它的作用是什么!)
  • “奇葩”理解~

不得不说,这种理解真的很奇葩,但是真的很形象!!!是我偶然一次在blink上看到的,虽然现在找不到那位同学了,如果你能看见,在这里给你表示感谢!我下面用图画和语言的形式来展现一下!

在这里插入图片描述

对应关系

  • 一串排列有序的萝卜坑&萝卜→数组&数组元素
  • 橙色萝卜→“新”数组元素,即不被移除元素
  • 红色萝卜→需被移除元素
  • 夫妻二人→双指针
    • 女生:快指针
    • 男生:慢指针

过程解析

 女生负责从一厢萝卜菜地的这头视察到那头for (int fastIndex = 0; fastIndex < nums.length; fastIndex++)
 男生负责挖坑nums[slowIndex++]
 如果遇到了橙色萝卜,女生会告诉男生:“把这个萝卜填到你挖的坑里面去,并且继续挖下个坑,可能还有橙色萝卜需要填”nums[slowIndex++] = nums[fastIndex]
遇到了红色萝卜,她什么也不说,直接跳过去,寻找下一个橙色萝卜if (nums[fastIndex] == val) { continue;//快指针遇到目标元素,即跳过 }
  如此进行下去,直到一厢菜地被视察完。
在这里插入图片描述

代码实现

class Solution {
    public int removeElement(int[] nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if (nums[fastIndex] == val) {
                continue;//快指针遇到目标元素,即跳过
            }
            nums[slowIndex++] = nums[fastIndex];//满指针指向正确元素的正确位置
        }
        return slowIndex;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

补充训练–验证

如果你还是对上面的理解将信将疑,不如看看下面这题,验证以上理解确实有用

26. 删除有序数组中的重复项
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

代码实现

class Solution {
    public int removeDuplicates(int[] nums) {
        int slowIndex = 0;
        for (int quickIndex = 0; quickIndex < nums.length; quickIndex++) {
            //如果在遍历时发现此元素和前面重复,直接跳过此元素
            if (quickIndex > 0 && nums[quickIndex] == nums[quickIndex - 1]) {
                continue;
            }
            //慢指针在后面“挖坑”等着接收
            nums[slowIndex++] = nums[quickIndex];
        }
        return slowIndex;
    }
}

write in the end:
后续还会更新很多双指针题目来加深对双指针的理解!还不快快关注![笔芯]

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/142452.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!