C++刷题笔记(2)——leetcode27、26、283

2024-02-02 19:32
文章标签 c++ 笔记 刷题 26 283 leetcode27

本文主要是介绍C++刷题笔记(2)——leetcode27、26、283,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

双指针法

双指针法利用两个指针对数组进行扫描,利用问题本身所给的序列特性(升序或降序),通常是相反方向的或者相同方向不同速度(快慢指针)

并非是一种算法,更像是一种变成技巧;

快慢指针中,在慢指针循环内定义快指针,快指针在慢指针之前,对数组后续元素依次扫描,在扫描到指定元素或者数组结尾的时候快指针返回,慢指针后移,并且根据题目要求移动或替换元素。

题目1:27.移除元素在这里插入图片描述

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖

暴力解法

两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组
在这里插入图片描述
暴力算法的解题思路很简单,就是遍历数组找到目标元素,然后依次移动目标元素后面的元素将其覆盖

class Solution {
public:int removeElement(vector<int>& nums, int val) {int size = nums.size();for (int i = 0; i < nums.size(); i++) {            //遍历数组if (nums[i] == val) {                          //发现需要移除的元素for (int j = i + 1; j < size; j++) {       //就将数组集体向前移动一位nums[j - 1] = nums[j];             }i--;                                       //因为下标i以后的数值都向前移动了一位,所以i也向前移动一位size--;                                    //此时数组的大小-1}}return size;}
};

双指针法

在这里插入图片描述
当碰到target数值,慢指针停止移动,快指针保持移动,并把快指针指向的数组元素移动到慢指针
单向双指针方法:
没有改变数组中元素的相对位置

//单向双指针
class Solution {
public:int removeElement(vector<int>& nums, int val) {int i = 0;                                         //i为慢指针for (int j = 0; j < nums.size() - 1; j++) {        //j为快指针,这里不能写j < nums.size() - 1,防止数组长度为1和0if (val != nums[j]) {nums[i++] = nums[j];                      //nums中的j元素如果不等于val,则慢指针后移一位,快指针后移一位}}                                                //若j等于val,则再次进入循环体,快指针后移,慢指针不动return i;}
};

单向双指针方法解题思路:
在这里插入图片描述
首先就是快指针、慢指针的索引初始为0,根据循环条件j < nums.size()进入循环,寻找数组中等于目标值的元素,这里要注意后置递增是先计算表达式、再对变量进行加1
在这里插入图片描述
直到i=2、j=2,此时j的值仍满足循环条件,但不满足if语句,因此不会执行if语句,直接执行j++,j=3
在这里插入图片描述
再次进行循环,j=3,满足循环条件且满足if语句,此时j=3、i=2,执行if语句会将进行赋值操作nums[2] = nums[3]; 完成移除元素操作
在这里插入图片描述
之后会依次将快指针的值赋给慢指针
在这里插入图片描述
当i=3、j=4时依然满足循环条件和if语句条件,继续进行一个循环后i=4、j=5,不再满足循环条件,返回i,返回移除后数组的新长度。
在这里插入图片描述

双向指针方法:
基于元素顺序可以改变的题目描述改变了元素相对位置,确保了移动最少元素

class Solution {
public:int removeElement(vector<int>& nums, int val) {int i = 0;                                      //左指针int j = nums.size() - 1;                        //右指针while (i <= j) {                                while (i <= j && nums[i] != val) {          //找左边等于val的元素,如果这里不加i <= j的限制,就可能i一直右移到j右边,造成数组长度不准确++i; }while (i <= j && nums[j] == val) {          //找右边不等于val的元素,这里i<=j同上--j;}if (i < j) {                                //将右边不等于val的元素覆盖左边等于val的元素,这里i<j没有等于,如果可以等于,那么执行i++、j--后同样i可能移动到j右边nums[i++] = nums[j--];}}return i;                                       //i一定指向了最终数组末尾的下一个元素}
};

双向指针方法解题思路:
在这里插入图片描述
这种解法的思路左指针从数组的左边开始遍历数组,寻找等于目标值的元素右指针从右开始遍历数组,寻找不等于目标值的元素
在这里插入图片描述
于是就有了等于目标值的元素的索引和正常的元素,用正常元素覆盖等于目标值的元素完成移除元素操作
在这里插入图片描述
之后左指针继续遍历数组,当左指针i=4时仍满足while (i <= j)while (i <= j && nums[i] != val)的循环条件,因此还会继续进行累加,累加后i=5,不再满足循环条件,返回i,返回移除后数组的新长度。
在这里插入图片描述

题目2:26.删除排序数组中的重复项

在这里插入图片描述
单向双指针方法:

class Solution {
public:int removeDuplicates(vector<int>& nums) {int i = 0;                                //i慢for (int j = 1; j < nums.size(); j++) {   //j快if (nums[i] != nums[j]) {i++;                              //移到下一位,将不同的数放入nums[i] = nums[j];}}return i + 1;                            //删除后数组的新长度}
};

单向双指针方法解题思路:
在这里插入图片描述
解题思路大概和27题差不多,当i=2、j=3时,将会跳过if语句,执行j++,此时i=2、j=4
在这里插入图片描述
继续执行代码i++;nums[i] = nums[j];(i=3,nums[3] = nums[4]),删除数组中的重复项,j++,此时i=3、j=5,不再满足循环条件,返回数组成都
在这里插入图片描述
然后进行j++,此时i=3、j=5,不再满足循环条件,返回数组长度。

题目3:283.移动零

在这里插入图片描述
这一题和27题非常的类似了
单向双指针方法:

class Solution {
public:void moveZeroes(vector<int>& nums) {int slowIndex = 0;for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {if (nums[fastIndex] != 0) {nums[slowIndex++] = nums[fastIndex];}}// 将slowIndex之后的冗余元素赋值为0for (int i = slowIndex; i < nums.size(); i++) {nums[i] = 0;}}
};

单向双指针方法解题思路:
主要解题思路就是用双指针遍历数组,当遇到0元素时,slowIndex不动,fastIndex+1,然后将快指针赋值给慢指针。

相当于对整个数组移除元素0,然后slowIndex之后都是移除元素0的冗余元素,把这些元素都赋值为0就可以了。

这篇关于C++刷题笔记(2)——leetcode27、26、283的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/671727

相关文章

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快