news 2026/5/4 17:19:01

双指针,数组去重

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双指针,数组去重

一、核心原理

  1. 慢指针(i):指向去重后新数组的最后一个有效位置

  2. 快指针(j):遍历整个原数组,寻找新的不重复元素

  3. 规则:

    • 找到不重复元素 → 赋值给慢指针的下一位,慢指针前进。

    • 找到重复元素 → 快指针直接跳过。


二、场景 1:有序数组去重(保留一个重复元素)

题目要求:

给定升序有序数组,原地删除重复元素,使每个元素只出现一次,返回新数组长度。

示例:[0,0,1,1,1,2,2,3,3,4]→ 去重后[0,1,2,3,4],返回长度 5。

#include <iostream> #include <vector> using namespace std; ​ // 有序数组去重,双指针核心函数 int removeDuplicates(vector<int>& nums) { // 边界:空数组直接返回 0 if (nums.empty()) return 0; ​ // 慢指针:初始指向第一个元素(新数组最后一位) int slow = 0; // 快指针:遍历整个数组 for (int fast = 1; fast < nums.size(); fast++) { // 找到不重复的元素 if (nums[fast] != nums[slow]) { slow++; // 慢指针前进 nums[slow] = nums[fast]; // 覆盖更新 } // 重复:快指针自动++,无需操作 } // 新数组长度 = 慢指针下标 + 1 return slow + 1; } ​ int main() { vector<int> nums = {0, 0, 1, 1, 1, 2, 2, 3, 3, 4}; int newLen = removeDuplicates(nums); ​ cout << "去重后数组长度:" << newLen << endl; cout << "去重后数组:"; for (int i = 0; i < newLen; i++) { cout << nums[i] << " "; } return 0; }

三、场景 2:有序数组去重(保留最多两个重复元素)

题目要求

每个元素最多出现 2 次,LeetCode 80 经典题。

示例:[1,1,1,2,2,3][1,1,2,2,3],返回 5。

int removeDuplicates2(vector<int>& nums) { if (nums.size() <= 2) return nums.size(); ​ int slow = 1; // 允许前两个元素保留 for (int fast = 2; fast < nums.size(); fast++) { // 核心:和 slow-1 比较,保证最多两个重复 if (nums[fast] != nums[slow - 1]) { slow++; nums[slow] = nums[fast]; } } return slow + 1; }

四、场景 3:无序数组去重(双指针通用版)

无序数组不能直接比较相邻元素,双指针 + 标记实现原地去重:

int removeDuplicatesUnordered(vector<int>& nums) { if (nums.empty()) return 0; ​ int slow = 0; for (int fast = 1; fast < nums.size(); fast++) { bool isDuplicate = false; // 检查 fast 是否在 slow 前面已出现 for (int k = 0; k <= slow; k++) { if (nums[fast] == nums[k]) { isDuplicate = true; break; } } // 不重复则加入新数组 if (!isDuplicate) { slow++; nums[slow] = nums[fast]; } } return slow + 1; }

建议用哈希表实现:O(n)时间

int removeDuplicates(vector<int>& nums) { unordered_map<int, bool> mp; int idx = 0; ​ for (int x : nums) { //遍历数组 /vector 等容器,不用写下标 if (!mp[x]) { mp[x] = true; nums[idx++] = x; } } ​ nums.resize(idx); return idx; }

五、总结

慢指针slow: 标记去重数组的最后位置

快指针fast: 遍历数组,寻找新元素

O(n)时间 ,O(1)空间

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 19:24:36

SenseVoice-Small ONNX量化版保姆级教程:Gradio前端一键部署实操

SenseVoice-Small ONNX量化版保姆级教程&#xff1a;Gradio前端一键部署实操 1. 开篇&#xff1a;让语音识别变得简单高效 如果你正在寻找一个既快又准&#xff0c;还能听懂多种语言的语音识别工具&#xff0c;那么SenseVoice-Small ONNX量化版绝对值得你花十分钟了解一下。想…

作者头像 李华
网站建设 2026/4/11 21:55:56

单相全桥逆变器Simulink仿真分析与MATLAB实现探索

单相全桥逆变器仿真&#xff0c;simulink&#xff0c;matlab打开Simulink新建空白模型&#xff0c;从库浏览器里拽出四个IGBT模块组成H桥结构的时候&#xff0c;我突然意识到全桥逆变器这玩意儿本质上就是个电子跷跷板——让电流在负载两端来回震荡。不过说人话就是&#xff1a…

作者头像 李华
网站建设 2026/4/10 19:22:43

利用GME多模态向量模型为AE视频片段自动生成标签与描述

利用GME多模态向量模型为AE视频片段自动生成标签与描述 每次打开After Effects&#xff0c;面对时间线上几十甚至上百个视频片段&#xff0c;你是不是也感到一阵头疼&#xff1f;给每个片段手动打标签、写描述&#xff0c;不仅枯燥乏味&#xff0c;还特别容易出错。尤其是在处…

作者头像 李华
网站建设 2026/4/12 2:13:52

Java Lambda 表达式入门指南:从匿名内部类到函数式接口

一、前言在 Java 8 之前&#xff0c;我们写代码时常常被冗长的匿名内部类困扰 —— 明明核心逻辑只有一两行&#xff0c;却要写一堆模板代码。Lambda 表达式的出现&#xff0c;彻底改变了这一现状&#xff0c;它让 Java 拥有了函数式编程的简洁&#xff0c;也让我们的代码更聚焦…

作者头像 李华
网站建设 2026/4/11 23:09:27

如何永久保存你的微信聊天记忆?WeChatMsg开源工具完整指南

如何永久保存你的微信聊天记忆&#xff1f;WeChatMsg开源工具完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…

作者头像 李华
网站建设 2026/4/12 4:15:32

BPMN-JS属性面板深度配置指南:Vue3+TS项目如何自定义右侧工具栏?

BPMN-JS属性面板深度配置指南&#xff1a;Vue3TS项目如何自定义右侧工具栏&#xff1f; 在当今企业级应用开发中&#xff0c;流程引擎的可视化配置已成为提升开发效率的关键环节。BPMN-JS作为业界领先的BPMN 2.0建模工具&#xff0c;其强大的属性面板定制能力常被低估。本文将…

作者头像 李华