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]
这篇博客介绍了LeetCode第283题《Move Zeroes》的四种Java解决方案,包括新建数组、ArrayList以及两种原地修改数组的方法。所有方法的时间复杂度为O(n),但前两种不满足原地修改的要求,后两种则实现了原地修改,空间复杂度为O(1)。
577

被折叠的 条评论
为什么被折叠?



