----------------------
- 涉及内容:
- 数组组内移位
- 2020/10/13
题目如下:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
补充知识点:
for( int num : nums ) --> foreach循环遍历数组nums中的每个数。
C++11中的swap时间复杂度能够达到常数级O(1),但对两个数组之间进行swap的话,是O(N)
解法:
- 解法 ① : 遍历,取零,挪位,零放置末尾
- 解法 ② : 两数组,不是零就放置新数组中,同时记录零的个数,最后再添加(不符题意)
- 解法 ③ : 双变量(最优解)
解法③实现: C++ Java
----------------------------------------------------------------------
- Java 单循环:
- 错步分析,两变量站在同一起点,i 变量不断迈步,j 变量一遇到零就走不动了,
- 为了使得 j 动起来,将 i 变量(不为零的变量)和 j 进行互换。然后奔向幸福的终点
- 时间复杂度:O(N)
- 空间复杂度:O(1),只使用了常量
----------------------------------------------------------------------
``Java
class Solution {
public void moveZeroes(int[] nums) {
int j = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] != 0) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
j++;
}
// 可将if循环里面的替换语句换成函数实现
//swap( nums[ j++] = nums[ i ] );
}
}
}
---------------------------------------------------------------------------
- C++ 双循环:
- 一循环,把所有非零元素接起来
- 二循环,余下空间全部补零
- 时间复杂度:O(N)
- 空间复杂度:O(1),只使用了常量
---------------------------------------------------------------------------
class Solution {
public void moveZeroes(vector<int>& nums) {
int j = 0;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] != 0) {
nums[j++] = nums[i];
}
}
for (;j < nums.size(); j++) {
nums[j] = 0;
}
/**
* while ( j < nums.size()) {
* nums[j++] = 0;
* }
*/
}
};