您的位置:首页 > 科技 > 能源 > 徐州智能模板建站_建筑网片厂_黄冈网站推广_西安百度网站快速排名

徐州智能模板建站_建筑网片厂_黄冈网站推广_西安百度网站快速排名

2025/4/21 22:41:21 来源:https://blog.csdn.net/tan_run/article/details/147259187  浏览:    关键词:徐州智能模板建站_建筑网片厂_黄冈网站推广_西安百度网站快速排名
徐州智能模板建站_建筑网片厂_黄冈网站推广_西安百度网站快速排名

📝前言说明:

  • 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:1,本人解法 + 本人屎山代码;2,优质解法 + 优质代码;3,精益求精,更好的解法和独特的思想(如果有的话)
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽

视频

  • 293. 移动零
    • 个人解
    • 优质解
  • 1089. 复写零
    • 个人解
    • 优质解:

293. 移动零

在这里插入图片描述


个人解

思路:请添加图片描述
用时:15:16,(真是没救了,写成这样)
屎山代码:通过

class Solution {
public:void moveZeroes(vector<int>& nums) {int n = nums.size();int slow = 0;int fast = 1;while(slow < n && fast < n){while(slow < n && nums[slow] != 0){slow++;}while(fast < n && (fast < slow || nums[fast] == 0)){fast++;}if(slow < n && fast < n){swap(nums[slow], nums[fast]);slow++;fast++;}}}
};

时间复杂度:O(n)
空间复杂度:O(1)


优质解

思路:整个数组可以划分成:已排序区[0, slow] + 零区[ slow + 1, fast ) + 待排序区[fast, n-1]
我屎山代码的问题:我的slowfast是分别移动的,后续还需要自己维护fast > slow
优质解法:

  • slow指针始终指向已排序区的最后一个元素,slow不主动移动,只在交换时移动,这样就可以始终用来标识已排序区的位置。
  • fast指针遍历数组,当fast != 0时,和slow + 1位置的0交换。
class Solution {
public:void moveZeroes(vector<int>& nums) {int slow = -1, fast = 0;for(fast = 0; fast < nums.size(); fast++){if(nums[fast]){swap(nums[fast], nums[slow + 1]);slow++;}}}
};

时间复杂度:O(n)
空间复杂度:O(1)


1089. 复写零

在这里插入图片描述

个人解

思路:一个指针在前,一个指针在后,前指针遇到0要复写的时候,通过后指针,把复写位置后的元素都往后移动一位,腾出空间。

用时:17:21
屎山代码:通过

class Solution {
public:void duplicateZeros(vector<int>& arr) {int n = arr.size();int slow = 0, fast = n - 1;while(slow < n - 1){if(arr[slow]){slow++;}else{slow++;for(fast = n - 1; slow < fast; fast--){arr[fast] = arr[fast - 1];}arr[slow] = 0;slow++;}}}
};

时间复杂度:O( n 2 n^2 n2)
空间复杂度:O(1)


优质解:

首先,我们先思考,如果不是就地操作的解法:
创建一个新的数组,然后一个指针cur指向原数组,一个指针dest指向新数组,dest根据cur的值不断进行复写操作。

那换成就地操作呢?
如果直接这么操作,那dest复写两次的时候就会覆盖还没有复写的值。

那能不能从后往前进行复写操作?
答案是可以的,问题是要先找到最后一个复写的数。

最后一个复写的数由什么决定?
如果我们看题不仔细,不认真思考的话就会简单认为:0的个数直接决定后面几个数会被移出数组外,如:若有3个0,那么倒数第4个数就是最后一个复写的数。(因为后3个数的位置 → 被前面复写的0个替代了)
但其实不然,因为:0有可能被移动出去

所以,重点又变成了,如何找最后一个要复写的数的位置。
方法:我们先模拟一遍复写的过程但是不复写,就可以让cur定位到最后一个要复写的元素,dest指向从后往前复写的第一个要复写的开始位置。
步骤:

  1. cur指向当前要复写的元素,遍历数组,dest指向已经复写完的位置(的最后一个)
  2. arr[cur] == 0dest移动两步,否则为一步
  3. 判断dest是否到达结束位置,达到了就提前退出循环。
    注意点1:在本次循环中的cur不能移动,因为cur指向的是要复写的,如果移动了就到了下一个没有复写的位置。
    注意点2:会有在数组外复写的情况:这种情况是在dest == n-1的时候还要复写两个0,解决方法:只需要让arr[n-1] = 0dest -= 2cur -= 1就行,因为这种情况下已确定最后一位写的是0

文字叙述晦涩难懂,建议画图

代码:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur = 0, dest = -1, n = arr.size(); // dest指向复写完的最后一个位置while(cur < n) {if(arr[cur]) dest++; else dest += 2;if(dest >= n-1) break; // dest = n-1 代表已经写完最后一个位置了cur++; // cur指向的元素代表要复写的元素}if(dest == n) // 代表在数组外面写了{arr[n-1] = 0;dest -= 2;cur -= 1;}while(cur >= 0){if(arr[cur]) arr[dest--] = arr[cur--];else{arr[dest--] = 0;arr[dest--] = 0;cur--;}}}
};

时间复杂度:O(n)
空间复杂度:O(1)

🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com