数组
双指针
题目描述
给定一个数组 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
进阶: 你能尽量减少完成的操作次数吗?
解法
方法一:双指针
我们使用两个指针 $i$ 和 $j$,其中指针 $i$ 指向当前已经处理好的序列的尾部,而指针 $j$ 指向待处理序列的头部。初始时 $i=-1$。
接下来,我们遍历 $j \in [0,n)$,如果 $nums[j] \neq 0$,那么我们就将指针 $i$ 指向的下一个数与 $nums[j]$ 交换,同时将 $i$ 后移。继续遍历,直至 $j$ 到达数组的尾部,该数组的所有非零元素就按照原有顺序被移动到数组的头部,而所有零元素都被移动到了数组的尾部。
时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。
Python3 Java C++ Go TypeScript Rust JavaScript C
class Solution :
def moveZeroes ( self , nums : List [ int ]) -> None :
i = - 1
for j , x in enumerate ( nums ):
if x :
i += 1
nums [ i ], nums [ j ] = nums [ j ], nums [ i ]
1
2
3
4
5
6
7
8
9
10
11
12 class Solution {
public void moveZeroes ( int [] nums ) {
int i = - 1 , n = nums . length ;
for ( int j = 0 ; j < n ; ++ j ) {
if ( nums [ j ] != 0 ) {
int t = nums [++ i ] ;
nums [ i ] = nums [ j ] ;
nums [ j ] = t ;
}
}
}
}
class Solution {
public :
void moveZeroes ( vector < int >& nums ) {
int i = -1 , n = nums . size ();
for ( int j = 0 ; j < n ; ++ j ) {
if ( nums [ j ]) {
swap ( nums [ ++ i ], nums [ j ]);
}
}
}
};
func moveZeroes ( nums [] int ) {
i := - 1
for j , x := range nums {
if x != 0 {
i ++
nums [ i ], nums [ j ] = nums [ j ], nums [ i ]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 /**
Do not return anything, modify nums in-place instead.
*/
function moveZeroes ( nums : number []) : void {
const n = nums . length ;
let i = 0 ;
for ( let j = 0 ; j < n ; j ++ ) {
if ( nums [ j ]) {
if ( j > i ) {
[ nums [ i ], nums [ j ]] = [ nums [ j ], 0 ];
}
i ++ ;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14 impl Solution {
pub fn move_zeroes ( nums : & mut Vec < i32 > ) {
let mut i = 0 ;
for j in 0 .. nums . len () {
if nums [ j ] != 0 {
if j > i {
nums [ i ] = nums [ j ];
nums [ j ] = 0 ;
}
i += 1 ;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14 /**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function ( nums ) {
let i = - 1 ;
for ( let j = 0 ; j < nums . length ; ++ j ) {
if ( nums [ j ]) {
const t = nums [ ++ i ];
nums [ i ] = nums [ j ];
nums [ j ] = t ;
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12 void moveZeroes ( int * nums , int numsSize ) {
int i = 0 ;
for ( int j = 0 ; j < numsSize ; j ++ ) {
if ( nums [ j ] != 0 ) {
if ( j > i ) {
nums [ i ] = nums [ j ];
nums [ j ] = 0 ;
}
i ++ ;
}
}
}