【力扣】复写零,栈 + 双指针法

2024-02-09 16:04
文章标签 复写 指针 力扣

本文主要是介绍【力扣】复写零,栈 + 双指针法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

复写零原题地址

方法一:双指针法

从前向后复写,会造成覆盖。所以,应该从后向前复写,这样我们可以考虑维护一个栈。遍历数组,如果遇到非零元素,就入栈一次;如果遇到零,就入栈两次。当栈中的元素个数超出数组的元素个数时,把栈中的元素重新从后向前写入数组即可

如:对于数组 [1 2 0 0 3 0 4] ,

1 :入栈 1 次: [1]

2 :入栈 1 次: [1 2]

0 :入栈 2 次: [1 2 0 0]

0 :入栈 2 次: [1 2 0 0 0 0]

3 :入栈 1 次: [1 2 0 0 0 0 3]

此时栈中元素个数和数组元素个数相等,重新写入数组即可。

再举一个例子,对于数组 [1 2 0 0 3 0 4 5]

1 :入栈 1 次: [1]

2 :入栈 1 次: [1 2]

0 :入栈 2 次: [1 2 0 0]

0 :入栈 2 次: [1 2 0 0 0 0]

3 :入栈 1 次: [1 2 0 0 0 0 3]

0 :入栈 2 次: [1 2 0 0 0 0 3 0 0]

此时栈中元素个数比数组元素个数多一个,需要去掉最后一个零,把 [1 2 0 0 0 0 3 0] 写入数组。

由于不允许开辟 O(N) 的额外空间,我们可以考虑用 top 来维护栈顶(即栈中的有效数据个数),模拟出入栈过程。假设数组长度为 n ,当 top<n 时,可以继续入栈

用下标 i 来记录要复写的元素,下标 j 来记录复写的目标位置。在前面模拟入栈的过程中,可以记录最后一个入栈的元素在数组中的下标,即 i 。由于是从后向前复写, j 要初始化为 n-1 。

对于栈中元素个数比数组元素个数多一个,即 top==n+1 的特殊情况,最后一个零只需要复写一次,其余情况正常复写即可。复写时,把 [0,i] 的元素按照是否为零进行分类,非零元素复写一次,零复写两次。

// 方法一:双指针
class Solution
{
public:void duplicateZeros(vector<int>& arr){int n = arr.size();int top = 0; // 记录栈顶int i = -1;// 模拟把数组元素放入栈中while (top < n){if (arr[++i]){++top;}else{top += 2;}}// i 表示要复写的数据// j 表示要复写的位置int j = n - 1;// 最后放入 2 个零导致栈中元素比数组多if (top == n + 1){arr[j--] = 0;--i;}while (j > 0){// 第一次复写arr[j--] = arr[i];// 零还需要复写第二次if (arr[i--] == 0){arr[j--] = 0;}}}
};

这篇关于【力扣】复写零,栈 + 双指针法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

两数之和--力扣1

两数之和 题目思路C++代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们在map中能够找到这个差值,就说明存在两个整数的和为目标值。 如果没有找到,就将当前循环的nums[i]以及下标i放入map中,以便后续查

C和指针:字符串

字符串、字符和字节 字符串基础 字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。 字符串长度就是字符串中字符数。 size_t strlen( char const *string ); string为指针常量(const修饰string),指向的string是常量不能修改。size_t是无符号数,定义在stddef.h。 #include <stddef.h>

力扣第347题 前K个高频元素

前言 记录一下刷题历程 力扣第347题 前K个高频元素 前K个高频元素 原题目: 分析 我们首先使用哈希表来统计数字出现的频率,然后我们使用一个桶排序。我们首先定义一个长度为n+1的数组,对于下图这个示例就是长度为7的数组。为什么需要一个长度为n+1的数组呢?假如说总共有三个数字都为1,那么我们需要把这个1放在数组下标为3的位置,假如说数组长度为n,对于这个例子就是长度为3,那么它的

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

C和指针:结构体(struct)和联合(union)

结构体和联合 结构体 结构体包含一些数据成员,每个成员可能具有不同的类型。 数组的元素长度相同,可以通过下标访问(转换为指针)。但是结构体的成员可能长度不同,所以不能用下标来访问它们。成员有自己的名字,可以通过名字访问成员。 结构声明 在声明结构时,必须列出它包含的所有成员。 struct tag {member-list} variable-list ; 定义一个结构体变量x(包含

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结,删除链表节点问题使用到列表,哈希表,递归比较容易超时,我觉得使用计数排序比较稳,处理起来也不是很难。 1. 力扣3217:从链表中移除在数组中的节点 1.1 题目: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。 示例 1: 输入: nums = [1,2,3], head = [1,2,3,