数组
双指针
题目描述
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示 :
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶: 你能尽量减少完成的操作次数吗?
解法
方法一:双指针
我们用一个指针 $k$ 记录当前待插入的位置,初始时 $k = 0$。
然后我们遍历数组 $\textit{nums}$,每次遇到一个非零数,就将其与 $\textit{nums}[k]$ 交换,同时将 $k$ 的值加 $1$。
这样我们就可以保证 $\textit{nums}$ 的前 $k$ 个元素都是非零的,且它们的相对顺序与原数组一致。
时间复杂度 $O(n)$,其中 $n$ 是数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。
Python3 Java C++ Go TypeScript Rust JavaScript C
class Solution :
def moveZeroes ( self , nums : List [ int ]) -> None :
k = 0
for i , x in enumerate ( nums ):
if x :
nums [ k ], nums [ i ] = nums [ i ], nums [ k ]
k += 1
1
2
3
4
5
6
7
8
9
10
11
12 class Solution {
public void moveZeroes ( int [] nums ) {
int k = 0 , n = nums . length ;
for ( int i = 0 ; i < n ; ++ i ) {
if ( nums [ i ] != 0 ) {
int t = nums [ i ] ;
nums [ i ] = nums [ k ] ;
nums [ k ++] = t ;
}
}
}
}
class Solution {
public :
void moveZeroes ( vector < int >& nums ) {
int k = 0 , n = nums . size ();
for ( int i = 0 ; i < n ; ++ i ) {
if ( nums [ i ]) {
swap ( nums [ i ], nums [ k ++ ]);
}
}
}
};
func moveZeroes ( nums [] int ) {
k := 0
for i , x := range nums {
if x != 0 {
nums [ i ], nums [ k ] = nums [ k ], nums [ i ]
k ++
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12 /**
Do not return anything, modify nums in-place instead.
*/
function moveZeroes ( nums : number []) : void {
let k = 0 ;
for ( let i = 0 ; i < nums . length ; ++ i ) {
if ( nums [ i ]) {
[ nums [ i ], nums [ k ]] = [ nums [ k ], nums [ i ]];
++ k ;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12 impl Solution {
pub fn move_zeroes ( nums : & mut Vec < i32 > ) {
let mut k = 0 ;
let n = nums . len ();
for i in 0 .. n {
if nums [ i ] != 0 {
nums . swap ( i , k );
k += 1 ;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13 /**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function ( nums ) {
let k = 0 ;
for ( let i = 0 ; i < nums . length ; ++ i ) {
if ( nums [ i ]) {
[ nums [ i ], nums [ k ]] = [ nums [ k ], nums [ i ]];
++ k ;
}
}
};
void moveZeroes ( int * nums , int numsSize ) {
int k = 0 ;
for ( int i = 0 ; i < numsSize ; ++ i ) {
if ( nums [ i ] != 0 ) {
int t = nums [ i ];
nums [ i ] = nums [ k ];
nums [ k ++ ] = t ;
}
}
}