算法入门 03双指针(简单 - 第二题)LeetCode 283
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门 03双指针(简单 - 第二题)LeetCode 283相关的知识,希望对你有一定的参考价值。
一、题目
1、题目描述
给定一个数组 n u m s nums nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
样例: n u m s = [ 0 , − 1 , 0 , 3 , 9 ] nums = [0,-1,0,3,9] nums=[0,−1,0,3,9],输出 [ − 1 , 3 , 9 , 0 , 0 ] [-1,3,9,0,0] [−1,3,9,0,0]
2、基础框架
- c++ 版本给出的基础框架代码如下,要求不采用任何的辅助数组,完成将所有零移动到末尾;
- 也就是空间复杂度要求 O ( 1 ) O(1) O(1)。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
}
};
3、原题链接
二、解题报告
1、思路分析
1)首先,我们定义两个指针 i i i 和 j j j,初始情况下 i = 0 i = 0 i=0, j = 1 j = 1 j=1。
2)当 j < n j \\lt n j<n 时, 有四种情况需要考虑了:
a)nums[i]==0, nums[j]==0
,这时候, i i i 不能动, j j j 自增,回到 2);
b)nums[i]==0, nums[j]<>0
,这两个元素继续交换,并且 i i i 自增,自增完毕如果和 j j j 相等,则 j j j 自增,回到 2);
c)nums[i]<>0, nums[j]==0
, i i i 自增,自增完毕如果和 j j j 相等,则 j j j 自增,回到 2);
d)nums[i]<>0, nums[j]<>0
, i i i 和 j j j 同时自增,回到 2);
- 循环的结束条件,一定是 j ≥ n j \\ge n j≥n,这个时候,末尾全是零。
2、时间复杂度
- 两个指针都只会递增各一次,所以时间复杂度为 O ( n ) O(n) O(n)。
3、代码详解
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if(nums.size() <= 1) {
return ; // (1)
}
int i = 0, j = 1;
while(j < nums.size()) {
if(!nums[i] && !nums[j]) { // (2)
++j;
}else if(!nums[i] && nums[j]) { // (3)
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
if(++i == j) ++j;
}else if(nums[i] && nums[j]) { // (4)
++i, ++j;
}else if(nums[i] && !nums[j]) { // (5)
if(++i == j) ++j;
}
}
}
};
- ( 1 ) (1) (1) 当只有一个元素的时候,不需要做任何操作,所以直接返回即可。
-
(
2
)
(2)
(2) 对应
nums[i]==0, nums[j]==0
的情况,是否等于零可以用!
来实现; -
(
3
)
(3)
(3) 对应
nums[i]==0, nums[j]<>0
的情况; -
(
4
)
(4)
(4) 对应
nums[i]<>0, nums[j]<>0
的情况; -
(
5
)
(5)
(5) 对应
nums[i]<>0, nums[j]==0
的情况;
三、本题小知识
可以用
if(x)
来判断表达式x
是否为真;用if(!x)
来判断表达式x
是否为假;
以上是关于算法入门 03双指针(简单 - 第二题)LeetCode 283的主要内容,如果未能解决你的问题,请参考以下文章
算法入门线性迭代(简单 - 第二题)LeetCode 206
算法入门深度优先搜索(简单 - 第二题)LeetCode 617
算法入门 01线性枚举(简单 - 第二题)LeetCode 557
⭐算法入门⭐《双指针》中等03 —— LeetCode 209. 长度最小的子数组