LeetCode官网题目地址:力扣
Java实现代码:
package array; import java.util.ArrayList; import java.util.Arrays; /** * @ClassName LeetCode283 * @Description 283. Move Zeroes: https://leetcode.com/problems/move-zeroes/description/ * @Author Jiangnan Cui * @Date 2022/10/23 18:47 * @Version 1.0 */ public class LeetCode283 { /** * @MethodName moveZeroes * @Description 方法1:新建一个数组,使用额外的空间存储元素 * 时间复杂度: O(n) * 空间复杂度: O(n) * 但是不满足题目要求 * @Author Jiangnan Cui * @Date 18:57 2022/10/23 */ public void moveZeroes(int[] nums){ // 新建一个数组来保存有效元素,注意新建数组时必须对对数组进行初始化,指定数组长度,此处指定数组长度为nums.length,初始化元素全部为0 int[] result = new int[nums.length]; // 指定result数组起始下标,记录nums数组不为0元素 int index = 0; // 遍历数组 for (int i = 0; i < nums.length; i++) { // 将所有非0元素存到result数组中 if(nums[i] != 0){ // 将不为0的元素添加到result数组中,同时index值加1 result[index++] = nums[i]; } // 数组元素为0时,不作任何处理 } // 注意此处不能直接使用nums = result,因为这样仅仅是引用地址的复制,方法调用后,引用指向消失,实际数组元素并未发生变化,还是原数组,要对数组元素逐一操作才可以 // 参见:https://www.likecs.com/show-205118157.html // nums = result; // 将result中的所有元素依次放入到nums数组的位置,替换nums原有数组元素 for (int i = 0; i < result.length; i++) { nums[i] = result[i]; } } /** * @MethodName moveZeroes2 * @Description 方法2:新建一个ArrayList,使用额外的空间来存储元素,相比数组而言,ArrayList初始化时不用直接指定长度,随着实际元素个数长度随之改变,可以节约空间 * 时间复杂度: O(n) * 空间复杂度: O(n) * 但是不满足题目要求 * @Author Jiangnan Cui * @Date 18:57 2022/10/23 */ public void moveZeroes2(int[] nums){ // 用ArrayList来保存不为0的数组元素 ArrayList<Integer> nonZeroElements = new ArrayList<Integer>(); // 遍历数组 for (int i = 0; i < nums.length; i++) { // 将所有非0元素存到nonZeroElements中 if(nums[i] != 0){ nonZeroElements.add(nums[i]); } } // 将nonZeroElements中的所有元素依次放入到nums开始的位置 for (int i = 0; i < nonZeroElements.size(); i++) { nums[i] = nonZeroElements.get(i); } // 将nums剩余的位置放置为0 for (int i = nonZeroElements.size(); i < nums.length; i++) { nums[i] = 0; } } /** * @MethodName moveZeroes3 * @Description 方法3:原地解决该问题,通过移动元素实现 * 时间复杂度: O(n) * 空间复杂度: O(1) * 满足题目要求 * @Author Jiangnan Cui * @Date 19:46 2022/10/23 */ public void moveZeroes3(int[] nums){ // 定义存储不为0元素的起始下标,其中,数组中下标[0,...,index)的元素均为非0元素,[index,...,i]均为0 int index = 0; // 遍历数组 for(int i = 0; i < nums.length; i++){ // 如果数组元素不为0 if(nums[i] != 0){ // 将不为0的元素存储到原数组中指定满足要求的下标索引处,同时让index从0开始依次放入数组元素不为0的元素 nums[index++] = nums[i]; } // 数组元素为0时,不做任何处理 } // 遍历数组结束后,将nums剩余的位置赋值为0,起止位置为index for(int i = index; i<nums.length; i++){ nums[i] = 0; } } /** * @MethodName moveZeroes4 * @Description 方法4:方法3通过移动元素实现,最终还要补0,可通过交换数组元素实现 * 时间复杂度: O(n) * 空间复杂度: O(1) * 满足题目要求 * @Author Jiangnan Cui * @Date 19:49 2022/10/23 */ public void moveZeroes4(int[] nums){ // 定义存储不为0元素的起始下标,其中,数组中下标[0,...,index)的元素均为非0元素,[index,...,i]均为0 int index = 0; // 遍历数组 for(int i = 0; i < nums.length; i++){ // 如果数组元素不为0 if(nums[i] != 0 ){ // 将指定位置的元素与不为0的元素进行交换,同时index大小加1,继续向右存储不为0的数组元素 swap(nums, index++, i); } // 数组元素为0时,不做任何处理 } // 遍历数组结束后,数组满足题目要求 } /** * @MethodName moveZeroes5 * @Description 方法5:在方法4的基础上进行优化,避免自己和自己进行交换 * 时间复杂度: O(n) * 空间复杂度: O(1) * 满足题目要求 * @Author Jiangnan Cui * @Date 19:49 2022/10/23 */ public void moveZeroes5(int[] nums){ // 定义存储不为0元素的起始下标,其中,数组中下标[0,...,index)的元素均为非0元素,[index,...,i]均为0 int index = 0; // 遍历数组 for(int i = 0; i < nums.length; i++){ // 如果数组元素不为0 if(nums[i] != 0 ){ // 将指定位置的元素与不为0的元素进行交换,同时index大小加1,继续向右存储不为0的数组元素 // 1.避免自己和自己交换,即指向同一个位置时,不交换 if(index == i){ // index加1右移,指定下一个满足要求的元素位置 index++; }else{// 2.是两个位置时,进行交换,同时index加1右移,指定下一个满足要求的元素位置 swap(nums, index++, i); } } } // 遍历数组结束后,数组满足题目要求 } /** * @MethodName swap * @Description 进行数组中两元素的交换 * @param: nums * @param: i * @param: j * @Author Jiangnan Cui * @Date 18:53 2022/10/23 */ private void swap(int[] nums,int i,int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } public static void main(String[] args) { int[] arr = {0,1,0,3,12}; (new LeetCode283()).moveZeroes(arr); System.out.println(Arrays.toString(arr)); int[] arr2 = {0,1,0,3,12}; (new LeetCode283()).moveZeroes2(arr2); System.out.println(Arrays.toString(arr2)); int[] arr3 = {0,1,0,3,12}; (new LeetCode283()).moveZeroes3(arr3); System.out.println(Arrays.toString(arr3)); int[] arr4 = {0,1,0,3,12}; (new LeetCode283()).moveZeroes4(arr4); System.out.println(Arrays.toString(arr4)); int[] arr5 = {0,1,0,3,12}; (new LeetCode283()).moveZeroes4(arr5); System.out.println(Arrays.toString(arr5)); } }
输出结果:
[1, 3, 12, 0, 0] [1, 3, 12, 0, 0] [1, 3, 12, 0, 0] [1, 3, 12, 0, 0] [1, 3, 12, 0, 0]