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

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

相关文章

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

【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)等都是利用了这种机制。