【LeetCode_27】移除元素

【LeetCode_27】移除元素

刷爆LeetCode系列

LeetCode27题:

github地址

有梦想的电信狗

前言

本文用C++实现LeetCode 第27题


题目描述

题目链接:https://leetcode.cn/problems/remove-element/

在这里插入图片描述

在这里插入图片描述

题目思路分析

目标分析

  1. 将数组中等于val的元素移除
  2. 原地移除,意味着时间复杂度为O(n),空间复杂度为O(1)
  3. 返回nums中与val值不同的元素个数

思路:双指针

  • src:用于扫描元素,从待扫描元素的第一个开始,因此初始下标为0
  • dst:指向数组中,最后一个位置正确的元素的下标,因此初始值为-1
  • count:记录赋值的次数,赋值的次数即为数组中与val值不同的元素个数,初始值为0

操作

  • nums[src] != val 时,说明:src位置的数无需被去掉,将其放在dst的下一个位置
    • dst先++,指向可以放入下一个无需被删除的元素的位置
    • nums[dst]赋值放入元素,之后src++
    • 计数器count++
  • nums[src] == val 时,说明src位置的数需要被去掉,src++略过该元素。
在这里插入图片描述

代码实现

  • 时间复杂度O(n)
  • 空间复杂度O(1)
classSolution{public:intremoveElement(vector<int>& nums,int val){int src =0, dst =-1;int count =0;while(src < nums.size()){if(nums[src]!= val){++dst; nums[dst]= nums[src]; src++;++count;}else{++src;}}return count;}};

算法代码优化

  • 时间复杂度O(n)
  • 空间复杂度O(1)

通过观察我们发现

  • dstcount自增的次数一样,且初值分别为0和-1,因此count == dst + 1
  • while循环内,if和else逻辑中,都执行了src++,因此ifelse中的src++可以省略,直接将src在循环中++
// 优化版intremoveElement(vector<int>& nums,int val){int src =0, dst =-1;while(src < nums.size()){if(nums[src]!= val){++dst; nums[dst]= nums[src];}++src;}return dst +1;}
  • 利用前置和后置++的特性最终优化,但不推荐这么写,因为算法的可读性下降了
classSolution{public:intremoveElement(vector<int>& nums,int val){int src =0, dst =-1;while(src < nums.size()){if(nums[src]!= val) nums[++dst]= nums[src++];else++src;}return dst +1;}};

以上就是本文的所有内容了,如果觉得文章对你有帮助,欢迎 点赞⭐收藏 支持!如有疑问或建议,请在评论区留言交流,我们一起进步

分享到此结束啦
一键三连,好运连连!
你的每一次互动,都是对作者最大的鼓励!征程尚未结束,让我们在广阔的世界里继续前行! 🚀

Read more

C++ 模板进阶:特化、萃取与可变参数模板

C++ 模板进阶:特化、萃取与可变参数模板

C++ 模板进阶:特化、萃取与可变参数模板 💡 学习目标:掌握模板进阶技术的核心用法,理解模板特化的深层应用、类型萃取的实现原理,以及可变参数模板的灵活使用,提升泛型编程的实战能力。 💡 学习重点:模板特化的进阶场景、类型萃取工具的设计与应用、可变参数模板的展开技巧、折叠表达式的使用方法。 一、模板特化进阶:处理复杂类型场景 💡 模板特化不只是针对单一类型的定制,还能处理指针、引用、数组等复杂类型,实现更精细的类型适配逻辑。 1.1 指针类型的模板特化 通用模板默认处理普通类型,我们可以为指针类型单独编写特化版本,实现指针专属的逻辑。 #include<iostream>#include<string>usingnamespace std;// 通用模板:处理普通类型template<typenameT>classTypeProcessor{public:staticvoidprocess(T data){ cout

By Ne0inhk

C++ 设计模式概述及常用模式

C++ 设计模式概述 本文介绍了C++中23种设计模式的分类及实现示例,主要分为三大类: 创建型模式(5个):单例模式(常用)、工厂方法模式(常用)、抽象工厂模式(常用)、建造者模式和原型模式。这些模式专注于对象的创建机制。 结构型模式(7个):适配器模式(常用)、桥接模式、组合模式和装饰器模式(常用)等。这些模式处理类和对象的组合方式。 行为型模式:未完整列出,但包含观察者模式等(未展示完整代码)。 文章通过简洁的C++代码示例展示了常用设计模式的实现方法,如单例模式通过私有构造函数和静态方法确保唯一实例,工厂方法模式通过抽象工厂类创建产品等。这些模式为解决特定设计问题提供了可重用的解决方案。 C++ 设计模式概述及常用模式 设计模式可分为三大类:创建型、结构型、行为型。以下是23个设计模式的分类及代码示例: 一、创建型模式(5个) 1. 单例模式(Singleton)⭐ 常用 classSingleton{private:static

By Ne0inhk
C++测试与调试:确保代码质量与稳定性

C++测试与调试:确保代码质量与稳定性

C++测试与调试:确保代码质量与稳定性 一、学习目标与重点 本章将深入探讨C++测试与调试的核心知识,帮助你确保代码的质量与稳定性。通过学习,你将能够: 1. 理解测试与调试的基本概念,掌握测试方法和工具 2. 学会使用单元测试框架,如Google Test和Catch2 3. 理解集成测试的重要性,确保系统的功能正确性 4. 学会使用调试工具,如GDB和Visual Studio调试器 5. 培养测试与调试思维,设计高质量的代码 二、测试的基本概念 2.1 测试的分类 测试可以分为以下几类: * 单元测试:测试单个函数或类的功能 * 集成测试:测试多个模块的集成功能 * 系统测试:测试整个系统的功能 * 验收测试:测试系统是否满足用户需求 * 性能测试:测试系统的性能指标 2.2 测试原则 测试应该遵循以下原则: * 测试应该尽可能早地进行 * 测试应该覆盖所有可能的场景 * 测试应该是自动化的

By Ne0inhk

Java + Vue 毕业设计选题效率提升指南:从脚手架到自动化部署的全链路优化

毕业设计季又到了,对于计算机专业的同学来说,用 Java 做后端,Vue 做前端,是一个非常经典且实用的技术栈组合。但很多同学在真正动手时,常常被各种“琐事”绊住,比如环境配半天、前后端接口对不上、部署时手忙脚乱,导致宝贵的开发时间被大量浪费。今天,我就结合自己带学弟学妹做毕设的经验,聊聊如何通过一套标准化的流程和工具,把 Java + Vue 毕设的开发效率提上去,让你把精力真正花在业务逻辑和创新点上。 1. 毕业设计效率痛点:我们到底在哪儿“卡”住了? 在开始技术选型之前,我们先得搞清楚,做 Java + Vue 毕设时,哪些环节最容易“掉链子”。根据我的观察,主要有这么几个: 1. 环境配置地狱:这是第一个拦路虎。A 同学的 MySQL 是 8.0,B 同学是

By Ne0inhk