【算法】双指针(二)-复写零

【算法】双指针(二)-复写零

目录

一、题目介绍

二、双指针原理

1.当前维护指针

1.2维护要求

(1)不能覆盖掉未产效元素

三、提交代码


一、题目介绍

1089. 复写零 - 力扣(LeetCode)

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

示例 1:

输入:arr = [1,0,2,3,0,4,5,0] 输出:[1,0,0,2,3,0,0,4] 解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]

示例 2:

输入:arr = [1,2,3] 输出:[1,2,3] 解释:调用函数后,输入的数组将被修改为:[1,2,3]

提示:

  • 1 <= arr.length <= 104
  • 0 <= arr[i] <= 9

二、双指针原理

扩容遍历指针当前维护指针从小维护到大1.当前维护指针

1.1维护方向-双指针(一)移动零1.2维护要求(1)不能覆盖掉未产效元素

超前式覆盖 就从结果后位开始 往回变回 在后追赶 逆序维护

三、提交代码

public void duplicateZeros(int[] arr) { //省去维护的覆盖 到结果后位,就成直接数步子了: int cur = 0; int dest = 0; while(dest < arr.length) { if(arr[cur] == 0) { dest += 2; }else { dest += 1; } cur++; } //从结果后位开始 往回在后追赶 逆序维护: if(dest == arr.length) { //两指针指向的 都是自然再向后移动到的,指向的 并未展开 对着覆值操作的,此时都往回一步就到 数组末尾操作值位置 dest--; cur--; } if(dest > arr.length) { dest--; cur--; //两指针都往回移回一步后 就可以对着开始 往回覆值操作了,但这里dest指向的是越界处,得手动 覆值调一下 arr[dest - 1] = arr[cur];//一定是之前cur指向了0的连续导致的,往回一步后的此时arr[cur]一定是0,连续覆两次 dest -= 2; cur--; } while(cur >= 0) { if(arr[cur] == 0) { arr[dest] = 0; arr[dest-1] = 0; dest -= 2; }else { arr[dest] = arr[cur]; dest--; } cur--; } }
public void duplicateZeros(int[] arr) { int dest = -1, cur = 0; while (dest < arr.length - 1) { // 希望dest留指在数组最后一个元素,是往回覆盖的位置起始位置 // 不用也行,dest上面保护到的,不会越界的:if(cur == arr.length) // cur已经遍历完 最后一个的动作区间也使完了;这是一个0都没有遇到,得cur越界判断一下的动作区间里 做了才移到 数组的最后一个元素位置 if(arr[cur] == 0) dest += 2; else dest++; cur++; // 维护的cur 就指在 留下有用元素的 最后一个 } cur--; if(dest == arr.length) { // cur结尾时遇到0,dest连移到数组外了 而不是刚好数组最后一个位置,如果越界可以赋值,也是正确维护完的 // 手动覆盖一次,不能对越界位置赋值 arr[dest - 1] = 0; // (越界位置一个0)、最后一个位置一个0 dest -= 2; cur--; } while (cur >= 0) { if(arr[cur] == 0) { arr[dest] = 0; arr[dest - 1] = 0; dest -= 2; }else { arr[dest] = arr[cur]; dest--; } cur--; } }

Read more

动态规划 —— dp 问题-买卖股票的最佳时机III

动态规划 —— dp 问题-买卖股票的最佳时机III

江河入海,知识涌动,这是我参与江海计划的第9篇。 1. 买卖股票的最佳时机III 题目链接: 123. 买卖股票的最佳时机 III - 力扣(LeetCode)https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/description/   2. 题目解析  3. 算法原理 状态表示:以某一个位置为结尾或者以某一个位置为起点    dp[i]表示:第i天结束之后,此时的最大利润 :两种情况:     1. f[i][j]表示:第i天结束之后,完成了j次交易,处于买入状态,此时的最大利润    2. g[i][j]表示:第i天结束之后,完成了j次交易,处于卖出状态,此时的最大利润 2. 状态转移方程

【C++:哈希表封装】用哈希表封装unordered_map和unordered_set

【C++:哈希表封装】用哈希表封装unordered_map和unordered_set

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶、测试开发要点全知道 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的C++专栏简介: C++的两个参考文档  老朋友(非官方文档):cplusplus 官方文档(同步更新):C++ 官方参考文档 set和multiset的参考文档:set、multiset map和multimap的参考文档:map、multimap unordered_set和unordered_multiset的参考文档:unordered_set、unordered_multiset unordered_map和unordered_multimap的参考文档: unordered_map、unordered_

考研408--数据结构--day17--外部排序

考研408--数据结构--day17--外部排序

(以下内容全部出自上述课程) 目录 * 外部排序 * 1. 外存、内存之间的数据结构 * 2. 外部排序原理 * 2.1 构造初始归并段 * 2.2 第一趟归并 * 2.3 第二趟归并 * 2.4 第三趟归并 * 3. 时间开销分析 * 4. 优化 * 4.1 多路归并 * 4.2 减少初始归并段数量 * 5. 小结 * 败者树 * 1. 多路平衡归并带来的问题 * 2. 败者树的构造 * 3. 败者树的使用 * 4. 败者树的实现思路(了解) * 5. 小结 * 置换-选择排序 * 1. 土办法构造初始归并段 * 2. 置换-选择排序 * 3.

《算法闯关指南:优选算法--前缀和》--25.【模板】前缀和,26.【模板】二维前缀和

《算法闯关指南:优选算法--前缀和》--25.【模板】前缀和,26.【模板】二维前缀和

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 25.【模板】前缀和 * 解法(前缀和): * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 26.【模板】二维前缀和 * 解法: * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 结尾: 前言: 聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法: