当前位置: 首页 > news >正文

深入解析:删除有序数组中的重复项 II——巧用双指针实现条件筛选

深入解析:删除有序数组中的重复项 II——巧用双指针实现条件筛选

在算法世界里,数组去重 是一道经典问题,尤其是面对 有序数组 时,我们如何在 保证元素相对顺序 的前提下,高效去重?LeetCode 第 80 题 “删除有序数组中的重复项 II” 就是这样一道挑战题。今天,我将深入解析 双指针技巧 如何帮我们解决这个问题,并通过 详细代码讲解,让你彻底掌握它的核心思想。


1. 题目理解

题目要求:

  • 在一个升序排列的数组中,删除重复的元素,但最多保留两个相同的元素
  • 返回新数组的长度,并保证原数组的前部分存储的是处理后的元素
  • 要求使用 O(1) 额外空间(即不能借助额外的数组存储)。

示例

输入: nums = [1,1,1,2,2,3]
输出: 5
处理后的数组: [1,1,2,2,3]

可以看到:

  • 原本 “1” 出现了三次,但我们只能 保留两个,因此去掉一个 “1”;
  • “2” 也出现了两次,符合要求,保留;
  • “3” 只出现了一次,符合要求,保留。

2. 解决思路——双指针法

由于数组 有序,我们可以利用 双指针技巧

  1. 快指针 (i) 负责遍历整个数组,寻找符合条件的元素;
  2. 慢指针 (j) 负责 存储符合条件的元素,保证最终数组的正确性。

同时,我们需要一个 计数变量 count,用于记录当前数字出现的次数:

  • 如果当前元素次数 ≤ 2,则将其存入结果数组;
  • 否则,跳过该元素

3. 代码详解

def removeDuplicates(nums):# 边界条件:空数组直接返回0if not nums:return 0# 初始化双指针:j 指向存储位置,count 记录当前元素出现次数j = 0  # 慢指针,最终数组的索引count = 1  # 当前元素出现次数# 遍历整个数组(快指针 i)for i in range(1, len(nums)):if nums[i] == nums[i - 1]:  # 如果当前元素与前一个相同count += 1else:count = 1  # 新数字,重置计数if count <= 2:  # 只存储最多两个相同元素j += 1nums[j] = nums[i]  # 赋值到正确位置return j + 1  # 返回新数组长度

4. 代码解析

(1) 双指针逻辑

  • i 从索引 1 开始遍历,用于检查每个元素;
  • j 存储符合条件的元素,保证最终数组正确。

(2) 条件筛选

  • 通过 count 记录 当前元素出现次数
    • 小于等于 2,则 存入数组
    • 超过 2,则 跳过,保证去重。

5. 示例运行

让我们来看实际执行过程:

nums = [1,1,1,2,2,3]
length = removeDuplicates(nums)
print(nums[:length])  # 输出:[1,1,2,2,3]

执行步骤:

  1. 处理 1,1,1 -> 保留 1,1,去掉多余 1
  2. 处理 2,2 -> 保留 2,2
  3. 处理 3 -> 保留 3

最终得到 去重后的数组 [1,1,2,2,3]


6. 时间复杂度与优化

  • 时间复杂度:O(n),因为我们只遍历一次数组;
  • 空间复杂度:O(1),不需要额外存储,仅靠原数组操作。

对于大数据场景,这是一个 高效且实用 的算法!


7. 结语:双指针——数组处理的神兵利器

这道题 充分考验了数据筛选与指针操作

  • 通过 快慢指针 实现数组的 原地去重
  • 通过 计数变量 确保符合 最多保留 2 个元素 的规则;
  • 代码结构清晰、逻辑合理,在实际开发中也能派上用场。
http://www.dtcms.com/a/172439.html

相关文章:

  • 【Leetcode 每日一题 - 补卡】838. 推多米诺
  • 掌握流量管理:利用 EKS Ingress 和 AWS 负载均衡器控制器
  • 用户模块 - IP归属地技术方案
  • TCP/IP协议深度解析:从分层架构到TCP核心机制
  • MySQL 复合查询
  • Spring AMQP源码解析
  • 英伟达语音识别模型论文速读:Fast Conformer
  • MongoDB入门详解
  • \documentclass[lettersize,journal]{IEEEtran}什么意思
  • 【计算机视觉】三维重建:tiny-cuda-nn:高性能神经网络推理与训练的CUDA加速库
  • n8n中Wait节点的使用详解:流程暂停与恢复的实战指南
  • K8S node ARP 表爆满 如何优化
  • DeepSeek-Prover-V2:数学定理证明领域的新突破
  • 20、数据可视化:魔镜报表——React 19 图表集成
  • 解决因字段过长使MYSQL数据解析超时导致线上CPU告警问题
  • 浅拷贝和深拷贝的区别
  • css使用aspect-ratio制作4:3和9:16和1:1等等比例布局
  • 华为云Astro大屏中桥接器、连接器、转化器以及数据源、数据集、资产管理等概念梳理
  • Leetcode刷题记录30——螺旋矩阵
  • linux-文件操作
  • FreeRTOS菜鸟入门(十一)·信号量·二值、计数、递归以及互斥信号量的区别·优先级翻转以及继承机制详解
  • 基于MATLAB图像中的圆形目标识别和标记
  • MCUboot 中的 BOOT_SWAP_TYPE_PERM 功能介绍
  • 2048游戏(含Python源码)
  • 大模型推理--从零搭建大模型推理服务器:硬件选购、Ubuntu双系统安装与环境配置
  • 定位理论第一法则在医疗AI编程中的应用
  • 【PaaS与AI融合】MLOps平台的架构设计
  • 【MCP Node.js SDK 全栈进阶指南】专家篇(1):MCP-SDK扩展与定制
  • 【实验笔记】Kylin-Desktop-V10-SP1麒麟系统知识 —— 开机自启Ollama
  • 软考 系统架构设计师系列知识点之杂项集萃(54)