热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何去除一个数组中的子元素中的双引号_如何去除有序数组的重复元素

读完本文,你不仅学会了算法套路,还可以顺便去LeetCode上拿下如下题目:开篇词读完本文,你不仅学会了算法套路࿰

读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:开篇词读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:开篇词读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:开篇词读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:

26.删除排序数组中的重复项

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

27.移除元素

283.移动零

-----------

我们知道对于数组来说,在尾部插入、删除元素是比较高效的,时间复杂度是 O(1),但是如果在中间或者开头插入、删除元素,就会涉及数据的搬移,时间复杂度为 O(N),效率较低。

所以上篇文章 O(1)时间删除/查找数组中的任意元素 就讲了一种技巧,把待删除元素交换到最后一个,然后再删除,就可以避免数据搬移。

PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在 labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。

有序数组/链表去重

先讲讲如何对一个有序数组去重,先看下题目:

20b05da7202946f2f5211c28e9a3a695.png

函数签名如下:

int removeDuplicates(int[] nums);

显然,由于数组已经排序,所以重复的元素一定连在一起,找出它们并不难,但如果毎找到一个重复元素就立即删除它,就是在数组中间进行删除操作,整个时间复杂度是会达到 O(N^2)。

PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在 labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。

简单解释一下什么是原地修改:

如果不是原地修改的话,我们直接 new 一个 int[] 数组,把去重之后的元素放进这个新数组中,然后返回这个新数组即可。

但是原地删除,不允许我们 new 新数组,只能在原数组上操作,然后返回一个长度,这样就可以通过返回的长度和原始数组得到我们去重后的元素有哪些了。

这种需求在数组相关的算法题中时非常常见的,通用解法就是我们前文 双指针技巧 中的快慢指针技巧

我们让慢指针 slow 走在后面,快指针 fast 走在前面探路,找到一个不重复的元素就告诉 slow 并让 slow 前进一步。这样当 fast 指针遍历完整个数组 nums 后,nums[0..slow] 就是不重复元素

int removeDuplicates(int[] nums) {if (nums.length == 0) {return 0;}int slow = 0, fast = 0;while (fast }

看下算法执行的过程:

8351825de4760721e776c8df27a4a3b6.png

再简单扩展一下,如果给你一个有序链表,如何去重呢?这是力扣第 83 题,其实和数组去重是一模一样的,唯一的区别是把数组赋值操作变成操作指针而已:

ListNode deleteDuplicates(ListNode head) {if (head == null) return null;ListNode slow = head, fast = head;while (fast != null) {if (fast.val != slow.val) {// nums[slow] = nums[fast];slow.next = fast;// slow++;slow = slow.next;}// fast++fast = fast.next;}// 断开与后面重复元素的连接slow.next = null;return head;
}

08b2519f17c2a1acf3eb301ccd6c76b8.png

移除元素

这是力扣第 27 题,看下题目:

767ec9e7fbdb1ba69ad8a36f2741468f.png

函数签名如下:

int removeElement(int[] nums, int val);

题目要求我们把 nums 中所有值为 val 的元素原地删除,依然需要使用 双指针技巧 中的快慢指针:

如果 fast 遇到需要去除的元素,则直接跳过,否则就告诉 slow 指针,并让 slow 前进一步。

这和前面说到的数组去重问题解法思路是完全一样的,就不画 GIF 了,直接看代码:

int removeElement(int[] nums, int val) {int fast = 0, slow = 0;while (fast }

注意这里和有序数组去重的解法有一个重要不同,我们这里是先给 nums[slow] 赋值然后再给 slow++,这样可以保证 nums[0..slow-1] 是不包含值为 val 的元素的,最后的结果数组长度就是 slow

PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在 labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。

移动零

这是力扣第 283 题,我来描述下题目:

给你输入一个数组 nums,请你原地修改,将数组中的所有值为 0 的元素移到数组末尾,函数签名如下:

void moveZeroes(int[] nums);

比如说给你输入 nums = [0,1,4,0,2],你的算法没有返回值,但是会把 nums 数组原地修改成 [1,4,2,0,0]

结合之前说到的几个题目,你是否有已经有了答案呢?

题目让我们将所有 0 移到最后,其实就相当于移除 nums 中的所有 0,然后再把后面的元素都赋值为 0 即可。

所以我们可以复用上一题的 removeElement 函数:

void moveZeroes(int[] nums) {// 去除 nums 中的所有 0// 返回去除 0 之后的数组长度int p = removeElement(nums, 0);// 将 p 之后的所有元素赋值为 0for (; p }// 见上文代码实现
int removeElement(int[] nums, int val);

至此,四道「原地修改」的算法问题就讲完了,其实核心还是快慢指针技巧,你学会了吗?

相关推荐:

  • 经典动态规划:0-1 背包问题
  • 手把手带你刷二叉树(第三期)

_____________

我的 在线电子书 有 100 篇原创文章,手把手带刷 200 道力扣题目,建议收藏!对应的 GitHub 算法仓库 已经获得了 70k star,欢迎标星!



推荐阅读
  • 在实际开发中,现在安卓端和后台之间的数据交互,一般都是用JSON来传递数据信息。JSON大家一般都比较熟悉。我这边就以实际项目中的后台传过来的情况和大家分析下及如何处理。比如后台返 ... [详细]
  • 自动化部署服务——AWS CodeDeploy 快速入门
    https:amazonaws-china.comcnblogschinagetting-started-with-codedeploy作为DevOps和微服务的深入践行者 ... [详细]
  •  很好的博客:https:blog.csdn.netqq_39809664articledetails79934516可持久化数组#include#inclu ... [详细]
  • 九日集训 Day 4 指针
    一、概念定义1、指针即地址计算机中所有的数据都必须放置在内存中,不同类型的数据占用的字节数也不一样,例如32位整型int占据4个字节,64位整型longlong占据8个字节,字符型 ... [详细]
  • DFS基本概念步骤优缺点典型例题递推基本概念直接或者间接调用自身的算法称为递归算法一般数据n ... [详细]
  • 我正在使用数组列表通过构建一个交互式菜单供用户选择来存储来自用户输入的值。到目前为止,我的两个选择是为用户提供向列表输入数据和读取列表的全部内容。到目前为止,我创建的代码由两个类组成。 ... [详细]
  • 在这一期的SendMessage函数应用中,我将向大家介绍如何利用消息函数来扩展树型列表(TreeView)控件的功能相信对于树型列表控件大家十分的熟悉, ... [详细]
  • 简单动态字符串redis里面很多地方都用到了字符串,我们知道redis是一个键值对存储的非关系型数据库,那么所有的key都是用字符串存储的,还有字符串类型,这些都是用字符串存储的 ... [详细]
  • 是不是zlib是这些库的压缩算法的实现库,而这么多库它们只是在打包的时候使用了zlib进行压缩而已.而具体的打包格式就有ZIP,BZIP2,GZ之分?但是在我们在用gz压缩时候通常之前 ... [详细]
  • 成功入职字节跳动Android岗,定级22,入职就是30K16薪
    Android线程间切换用什么,Handler的运行机制是什么?Android处理异步任务用什么,AsyncTask线程池溢出是怎么回事& ... [详细]
  • 字符串匹配: BF与KMP算法
    文章目录一.BF算法1.算法思想2.代码实现二.KMP算法1.算法思想概述2.理解基于最长相等前后缀进行匹配3.代码中如何实现next数组5.代码实现6.next数组的优化一.BF ... [详细]
  • 题目描述输入整型数组和排序标识,对其元素按照升序或降序进行排序(一组测试用例可能会有多组数据)本题有多组输入,请使用whil ... [详细]
  • 这篇文章将为大家详细讲解有关C#开发技巧有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。C#开发技 ... [详细]
  • 一篇文章帮助您了解什么是云游戏以及它的优势和缺点
    云游戏是云计算的一个子类别。与电影和连续剧非常相似,游戏可以流式传输到用户的设备以播放内容。详细了解云游戏、其技术背景、优缺点以及市场上最好的云游戏提供商。相信随着技术的不断发展, ... [详细]
  • 题目描述:给你一棵二叉树的根节点root,请你返回层数最深的叶子节点的和。示例1:输入:root[1,2,3,4,5,n ... [详细]
author-avatar
游山玩水人生
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有