【优选算法必刷100题】第001~002题(双指针算法):移动零、复写零问题求解

【优选算法必刷100题】第001~002题(双指针算法):移动零、复写零问题求解

🔥个人主页:艾莉丝努力练剑

❄专栏传送门:《C语言》《数据结构与算法》C语言刷题12天IO强训LeetCode代码强化刷题洛谷刷题C/C++基础知识知识强化补充C/C++干货分享&学习过程记录测试开发要点全知道Linux操作系统编程详解笔试/面试常见算法:从基础到进阶

🍉学习方向:C/C++方向学习者

⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平



目录

001  移动零

1.1  思路

1.2  算法原理

1.3  代码实现  

1.4  过程推算

002  复写零

2.1  思路

2.2  算法原理

2.3  代码实现  

2.4  过程推算

结尾


001  移动零

力扣链接:283. 移动零

力扣题解链接:双指针求解【移动零】问题

题目描述:

1.1  思路

双指针算法——

创建两个数组,cur和dest——

cur:从左往右扫描数组,遍历数组

dest:已处理的区间内,非零元素的最后一个位置

cur往后遍历数组的过程中:

1、遇到0元素:cur++;

2、遇到非零元素:swap(nums[dest+1],nums[cur]),然后dest++,cur++。

也就是说——

算法思路:

在本题中,我们可以用一个cur指针来扫描整个数组,另一个dest指针用来记录非零数序列的最后一个位置。根据cur在扫描过程中遇到的不同的情况,分类处理,实现数组的划分。

在cur遍历期间,使得[0 , dest]的元素全部都是非零元素,[dest + 1 , cur - 1]的元素都是零。

1.2  算法流程

1.2.1 

初始化cur = 0(用来遍历数组),dest = -1(指向非零元素序列的最后一个位置。因为刚开始我们也不知道最后一个非零元素到底在什么位置,因此初始化为-1)

1.2.2

cur依次往后遍历每个元素,遍历到的元素会有下面两种情况:

1、遇到的元素都是0,cur直接++。因为我们的目标是让[dest + 1 , cur - 1]内的元素全都是零,因此当cur遇到0的时候,直接++,就可以让0在cur - 1的位置上,从而在[dest + 1 , cur - 1]内;

2、遇到的元素不是0,dest++,并且交换cur位置和dest位置的元素(swap),之后让cur++,扫描下一个元素。

(1)因为dest指向的位置是非零元素区间的最后一个位置,如果扫描到一个新的非零元素,那么它的位置就应该在dest + 1的位置上,因此dest先自增1;

(2)dest++之后,指向的元素就是0元素(因为非零元素区间末尾的后一个元素就是0),因此可以交换到cur所处的位置上,实现[0 , dest]的元素全部都是非零元素,[dest + 1 , cur - 1]的元素都是零。

1.3  代码实现  

代码演示:

class Solution { public: void moveZeroes(vector<int>& nums) { for(int dest = -1,cur = 0;cur < nums.size();cur++) { if(nums[cur]) swap(nums[++dest],nums[cur]); } } };
时间复杂度:O(N),空间复杂度:O(1)。

1.4  过程推算

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下!


002  复写零

力扣链接:1089. 复写零

力扣题解链接:双指针算法解决【复写零】问题

题目描述:

2.1  思路

双指针算法——

先根据“异地”操作,然后优化成双指针下的“就地”操作。

1、先找到最后一个“复写”的数: 双指针算法——

(1)先判断cur位置的值;

(2)决定dest向后走一步还是两步;

(3)判断一下dest是否已经到结束位置;

(4)cur++。

2、处理一下边界情况——

到达n-1位置,cur--,dest -= 2,复写两次0。

3、“从后往前”完成复写操作。

也就是说——

如果“从前向后”进行原地复写操作的话,由于0的出现会复写两次,导致没有复写的数会被覆盖掉。因此我们选择“从后往前”的复写策略。

但是我们选择“从后往前”的复写的时候,需要找到“最后一个复写的数”,因此我们的大体流程分两步:(1)先找到最后一个复写的数;(2)然后从后往前进行复写操作。

2.2  算法流程

2.2.1

初始化两个指针cur = 0,dest = 0;

2.2.2

找到最后一个复写的数:

1、当cur < n的时候,一直执行下面循环:

(1)判断cur位置的元素:

1)如果是0的话,dest就往后移动两位;

2)否则,dest往后移动一位。

2.2.3

判断dest是否越界到n的位置:

1、如果越界,执行以下三步:

(1)n - 1位置的值修改成0;

(2)cur向前移动一步;

(3)dest向前移动两步。

2.2.4

从cur位置开始往前遍历原数组,依次还原出复写后的结果数组:

1、判断cur位置的值:

(1)如果是0:dest以及dest - 1位置修改成0,dest -= 2;

(2)如果非零:dest位置修改成0,dest -= 1;

2、cur--,复写下一个位置。

2.3  代码实现  

代码演示:

class Solution { public: void duplicateZeros(vector<int>& arr) { //1、先找到最后一个数 int cur = 0,dest = -1,n = arr.size(); while(cur < n) { if(arr[cur]) { dest++; } else { dest += 2; } if(dest >= n - 1) break; cur++; } //2、处理边界问题 if(dest == n) { arr[n -1] = 0; cur--; dest -= 2; } //3、从后往前完成复写操作 while(cur >= 0) { if(arr[cur]) arr[dest--] = arr[cur--]; else { arr[dest--] = 0; arr[dest--] = 0; cur--; } } } };
时间复杂度:O(N),空间复杂度:O(1)。

2.4  过程推算

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下!


结尾

结语:本文内容到这里就结束了,大家不要忘记给博主“一键四连”哦!

Read more

Bellman - Ford 算法与 SPFA 算法求解最短路径问题 ——从零开始的图论讲解(4)

Bellman - Ford 算法与 SPFA 算法求解最短路径问题 ——从零开始的图论讲解(4)

目录 前言 为什么Dijkstra算法面对负权值图会有误差??? 举例说明 什么是Bellman -Ford算法? BF算法的核心思想  什么是松弛  为什么最多松弛N-1次? 代码实现 举例  初始状态(dist[] 数组)  第 1 轮松弛(遍历所有边) 第 2 轮松弛 第 3 轮松弛 第 4 轮松弛(最后一次) 第 5 轮检测是否还能松弛(负环判断) 完整代码  BF算法的缺陷 SPFA算法 SPFA算法改进的地方 SPFA算法的原理 完整代码 结尾 前言 这是笔者图论系列的第四篇博客了,非常感谢大家的支持,因为本系列的数据很好看,笔者有了更多动力去更新 . 前三篇URL如下: 1. 图的概念,图的存储,图的遍历与图的拓扑排序——从零开始的图论讲解(

By Ne0inhk
当AI变成“需求读心术大师“:Python开发者如何用“脑洞算法“破解预测困局?

当AI变成“需求读心术大师“:Python开发者如何用“脑洞算法“破解预测困局?

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎点赞 + 收藏 + 关注哦 💕 当AI变成"需求读心术大师":Python开发者如何用"脑洞算法"破解预测困局? 📚 本文简介 本文探讨了AI需求预测的局限性及其与人类心理洞察的本质差异。通过Python代码示例(GradientBoostingClassifier模型)揭示了AI"读心术"实为基于历史数据的概率猜测,并运用mermaid图对比展示AI在情感理解、文化背景考量等方面的不足。关键发现: AI预测依赖表面行为数据,而人类能理解深层动机 开发者应结合算法与人文洞察,如文中小陈从"更快的马"解读出"便捷交通工具"的真实需求 提出Python开发场景对照表,显示人类在用户体验设计、错误处理等方面的温度优势 结论:AI预测是工具而非真理,开发者需保持批判思维,

By Ne0inhk
数据结构-堆的实现和应用

数据结构-堆的实现和应用

目录 1.堆的概念 2.堆的构建 3.堆的实现 4.堆的功能实现 4.1堆的初始化 4.2堆的销毁 4.3堆的插入 4.3.1向上调整 4.4堆的删除 4.4.1向下调整法 编辑4.5取堆顶 5. 向上调整法和向下调整法比较  6.堆的应用 6.1TOP-K问题 6.2TOP-K思路 6.2.1用前n个数据来建堆 6.2.2剩下的N-K  6.3示例 1.堆的概念 堆的底层是数组,所以堆也是一种特殊的数组。 堆分为大堆和小堆 * 大堆:父节点不小于子节点 * 小堆:父节点不大于子节点

By Ne0inhk