移动零
[原题链接](初级算法 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com))
/**
* 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
* 必须在原数组上操作,不能拷贝额外的数组。
* 尽量减少操作次数。
*/
public class Solution {
/**
* 法一:冒泡
* @param nums
*/
public void moveZeroes1(int[] nums) {
for (int i = 0, j = nums.length - 1; i < j; ) {
if (nums[i] == 0) bubbling(nums, i, j--);
else i++;
}
}
private void bubbling(int[] nums, int index, int des){
if (index == des) return;
int temp;
for (int i = index; i < des; i++) {
temp = nums[i];
nums[i] = nums[i + 1];
nums[i + 1] = temp;
}
}
/**
* 法二
* 思路:冒泡法改进,每次冒泡忽略0
*/
public void moveZeroes2(int[] nums) {
int temp;
for (int i = 0, j = i; i < nums.length - 1; j = ++i) {
while (nums[j] == 0){
if (++j == nums.length) return;
}
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
/**
* 法三:
* 思路:从数组末端顺序找0,
* 找到则将0后的元素前移一位,并在数组最后补0
* 时间复杂度O(n^2)
* @param nums
*/
public void moveZeroes3(int[] nums) {
if (nums.length == 1) return;
for (int i = nums.length - 1; i >= 0; i--) {
//找到0
if (nums[i] == 0) {
//i后的元素前移
for (int j = i; j < nums.length - 1; j++) {
nums[j] = nums[j + 1];
}
//补0
nums[nums.length - 1] = 0;
}
}
}
/**
* 法四:
* 思路:用i、j遍历数组,i遇0则停
* 每当j遇到非0值,则j所在的元素(非0值)与i所在的元素(0)交换,
* 这样i就可以++了,循环这个过程,直到j“通过”数组,i必定到达了它所能到达的
* 最远的位置,i所到达的位置元素便非0了,且相对顺序不变。
* 这样数组的0值便移动到了数组末尾。
* 时间复杂度O(n)
* @param nums
*/
public void moveZeroes4(int[] nums){
//遇0则停
int i = 0;
int temp;
for (int j = 0; j < nums.length; j++) {
if (nums[j] != 0) {
temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
i++;
}
}
}
}