删除排序数组中的重复项

  • 题目描述:

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

  • 示例 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)

  • 快慢指针法:

慢指针维护无重复数组,快指针用于遍历查找无重复项,将找到的无重复项赋值给slow指针维护

画图举例详细说明:

(1)初始 slow指向首元素  快指针fast和fast+1同步后移查找

(2)当找到无重复项 slow后移  然后将fast+1对应进行赋值给slow

代码只有几行,一看就懂,注意一点,slow开始指向第一个元素不变,找到下一个后slow必选先后移然后再赋值,否则会覆盖slow维护的首元素

int removeDuplicates(int* nums, int numsSize){if(nums==NULL||numsSize==0)return 0;int slow=0;for(int fast=0;fast<numsSize-1;fast++){if(nums[fast]!=nums[fast+1]){slow++;//统计数组中无重复数字nums[slow]=nums[fast+1];//无重复数字前移合并 slow指针维护}}return slow+1;
}
  • 解题思路(2)

  • 遍历查询法

下面介绍的这种方法,一般初学者,比较容易想到这种解题思路,依然是延续了快慢指针的思路,但是快指针不是同步移动,然后设置start和end取找无重复项的边界,此方法虽然想法简单,但通过代码实现过程中非常容易出现bug,对此我就将我出现的情况进行描述:

(1)此方法end向后查找的过程中,找到不重复的项,通过end更新start的位置,并将start对应位置的值赋值给new指针维护无重复项数组

(2)看似很简单的问题,不就是向后查找吗,谁不会,但问题就出在这,首先是end结束的条件

我们先来考虑这样一段代码:

while(end<numsSize&&nums[start]==nums[end]){end++;}

在这个while循环里,我们注意到使用了&&关系运算符,我们知道   条件1&&条件2,条件1为真还需要检查条件2,但条件1为假,直接结束整个表达式结果为假

对此,我们考虑一下,为什么要先将end<numsSize作为条件1?条件1 和条件2互换可以么?

好吧,这里就是第一个坑!!!

我们来讨论一下,如果条件2在前,为真,继续检查end<numsSize真假,此时如果end已经越界,在nums[start]==nums[end]过程中将出现数组访问越界

如果条件1在前,先判断end是否越界,为后续数组赋值操作提供安全的访问环境

(3)接下来介绍下一个坑,在这种思路下,不同于快慢指针法,快指针两个之间满足fast+1关系,由于start和end不存在关系,所以在遍历到最后两个元素需要分情况讨论:

最后两个元素 存在两种情况

  • 相等情况下,由于start必定不会超越size  所以无论start倒数第一个元素还是倒数第二个元素  只需要将start对应位置元素赋值给new即可
while(start<numsSize){nums[new++]=nums[start];//相等情况下,start不会超越size  所以无论start倒数第一个元素还是倒数第二个元素  只需要将start对应位置元素赋值给new即可while(end<numsSize&&nums[start]==nums[end]){end++;}start=end;end++;}
  • 不相等情况  end此时可能会出现越界超过size,此时更新后start指向末尾元素,与上面情况不同 在上面操作中end越界,循坏结束,此时最后一个元素漏掉无法赋值给new   此时需要强行将末尾元素加入new
if(start==numsSize-1){nums[new++]=nums[start];}

整体代码如下:

int removeDuplicates(int* nums, int numsSize)
{int start=0,end=1;int new=0;while(start<numsSize){nums[new++]=nums[start];//最后两个元素 存在两种情况://相等情况下,start不会超越size  所以无论start倒数第一个元素还是倒数第二个元素  只需要将start对应位置元素赋值给new即可while(end<numsSize&&nums[start]==nums[end]){end++;}start=end;end++;}//不相等情况 end此时越界超过size,此时更新后start指向末尾元素,与上面情况不同 在上面操作中end越界,循坏结束,此时最后一个元素漏掉无法赋值给new   需要强行将末尾元素加入newif(start==numsSize-1){nums[new++]=nums[start];}return new;
}

参考来源:leetcode算法

删除排序数组的重复项(两种解法思路分享)相关推荐

  1. python去重复排序_Python实现删除排序数组中重复项的两种方法示例

    本文实例讲述了Python实现删除排序数组中重复项的两种方法.分享给大家供大家参考,具体如下: 对于给定的有序数组nums,移除数组中存在的重复数字,确保每个数字只出现一次并返回新数组的长度 注意:不 ...

  2. leetcode第26题:删除排序数组的重复项

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 给定数组 ...

  3. 删除排序数组的重复项

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...

  4. Java/26. Remove Duplicates from Storted Array 删除排序数组的重复项

    题目 . 代码部分(10ms 97.32%) class Solution {public int removeDuplicates(int[] nums) {int n = 0;boolean fl ...

  5. 删除排序数组中重复元素的方法

    文章目录 1.删除重复元素,所有元素只保留一次 2.重复元素保留不超过2次 在上一篇文章中讨论了关于如何删除排序链表中重复元素的方法.那么如果底层数据结构是数组又将如何处理呢? 1.删除重复元素,所有 ...

  6. LeetCode刷题:删除有序数组的重复项详解

    题目 Given a sorted array, remove the duplicates in place such that each element appear only once and ...

  7. 二维数组中的查找(两种解法,各有千秋)

    凡事都有可能,永远别说永远.--<放牛班的春天> 今天一题为再一个行列都有序的二维数组中寻找一个目标值,我们第一时间想到的可能是很暴力的解法,例如从头到尾进行遍历,这样能做出来,但是借用武 ...

  8. c++两个数组对比去掉重复的元素_每日一道 LeetCode (8):删除排序数组中的重复项和移除元素...

    ❝ 每天 3 分钟,走上算法的逆袭之路. ❞ 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub:https://github.com/meteor1993/LeetCode Gi ...

  9. vue删除数组中的一条数据_删除排序数组中的重复项 II

    删除排序数组中的重复项 II题目 给定一个增序排列数组 nums ,你需要在 原地 删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在 原地 修改 ...

最新文章

  1. 在 react 里使用 antd
  2. Python的enumerate()的坑
  3. python的列表的remove()方法、判断if xxx in xx条件比较耗时问题
  4. Fast R-CNN论文详解
  5. 配置windows 2008 作为远程访问SSL-×××服务器系列之二
  6. 并发编程(多进程1)
  7. linux sh 编程,Linux shell 编程入门
  8. 突然!华为P30 Pro真机上手视频曝光:屏幕指纹解锁秒开
  9. 移动应用测试基于JAVA_Appium用于测试Android混合移动应用程序
  10. 知识表示与计算机,两分钟了解人工智能中的“知识与知识表示”
  11. UEditor 百度Web编辑器 - JSP版本的使用
  12. C++ 正则表达式教程:C++ 中的正则表达式与示例
  13. OpenStack在天河二号的大规模部署实践(转)
  14. 树莓派4B设置USB启动
  15. 两台 计算机如何建立共享,怎么建立两个电脑的共享
  16. MyBatis和Hibernate的区别
  17. 模仿探探(百合网,珍爱网)卡片左右滑动效果,滑动流畅,卡片view无限重生
  18. 【iOS遇到的问题】switch控件--在设置switch按钮状态为on或者off,运行app,模拟器黑屏
  19. 【如何处理Windows 8 系统自带微软拼音简捷输入法无法删除】
  20. 丢手帕问题 java_初学java丢手帕问题

热门文章

  1. pdf转换成jpg教程
  2. 怎样用Unity Terrain工具制作美观的场景(一)
  3. Visual Studio 2015试用期过期,密钥激活
  4. 干电池升压IC,电流大,常用,功耗低
  5. linux probe函数调用,【整理】Linux驱动中,probe函数何时被调用
  6. TensorFlow的基础概念05
  7. 腾讯qq2014官方正式版 v6.3.12390 免费版
  8. JUL简介及组件介绍
  9. 面试经典--两个房间 每间房间三盏灯
  10. Network笔记整理 - 网络协议与网络分层