挑战刷leetcode第24天 (移动零-283)

124 阅读4分钟

哪吒教你如何“乾坤大挪移”——移动零的递归与坚持

大家好,我是哪吒,今天咱们不闹海,也不打妖怪,来聊聊一个看似简单却暗藏玄机的问题——移动零。这个问题就像是我在陈塘关的日常,总得把那些捣乱的“零”们赶到一边,让其他数字安安静静地过日子。

问题描述

给定一个数组 nums,我们需要把所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。听起来是不是有点像我在陈塘关的日常?把那些捣乱的“零”们赶到一边,让其他数字安安静静地过日子。

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

输入: nums = [0]
输出: [0]

基础版:双层循环

首先,我们来看看基础版的解决方案。这个版本就像是我刚学会法术时的样子,虽然有点笨拙,但效果还不错。

说明:借用的图片,为了更生动的描述

public void moveZeroes(int[] nums) {
    if (nums == null) {
        return;
    }
    int j = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            nums[j] = nums[i];
            j++;
        }
    }
    for (int i = j; i < nums.length; i++) {
        nums[i] = 0;
    }
}

思路解析:

  1. 第一层循环:我们遍历数组,找到所有非零元素,并把它们按顺序放到数组的前面。这个过程就像是我在陈塘关巡逻,把那些捣乱的“零”们一个个揪出来。
  2. 第二层循环:在第一层循环结束后,我们把剩下的位置都填上 0。这就像是我把那些捣乱的“零”们赶到一边,让它们安安静静地待着。

进阶版:单层循环

接下来,我们来看看进阶版的解决方案。这个版本就像是我修炼多年后的样子,法术更加娴熟,效率也更高。

说明:借用的图片,为了更生动的描述

public void moveZeroes(int[] nums) {
    if (nums == null) {
        return;
    }
    int j = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
            j++;
        }
    }
}

思路解析:

  1. 单层循环:我们只需要一次遍历,就能完成所有操作。这就像是我在陈塘关巡逻时,一边走一边把捣乱的“零”们赶到一边。
  2. 交换操作:当我们遇到一个非零元素时,就把它和当前 j 位置的元素交换。这就像是我在巡逻时,一边走一边把捣乱的“零”们赶到一边,同时把其他数字安安静静地放在前面。

递归方式:乾坤大挪移

现在,我们来聊聊递归方式。递归就像是我在陈塘关的日常,总得把那些捣乱的“零”们一个个揪出来,然后赶到一边。

思路解析:

  1. 递归终止条件:当 i 超过数组长度时,我们把剩下的位置都填上 0。这就像是我在陈塘关巡逻到最后,把那些捣乱的“零”们赶到一边。
  2. 递归调用:当我们遇到一个非零元素时,就把它放到 j 位置,然后递归处理下一个元素。这就像是我在巡逻时,一边走一边把捣乱的“零”们赶到一边,同时把其他数字安安静静地放在前面。

坚持的意义

无论是基础版、进阶版还是递归方式,解决问题的关键在于坚持。就像我在陈塘关的日常,总得把那些捣乱的“零”们一个个揪出来,然后赶到一边。虽然过程可能有些繁琐,但只要我们坚持不懈,最终一定能达到目标。

结语

好了,今天的“乾坤大挪移”就讲到这里。希望大家在解决问题的过程中,也能像我一样坚持不懈,最终达到目标。如果你觉得这篇文章对你有帮助,别忘了点赞、分享哦!下次再见,咱们继续聊更多有趣的技术问题!


哪吒小贴士:  递归虽然强大,但也容易陷入“无限循环”的陷阱。所以在使用递归时,一定要记得设置好终止条件,否则就像我在陈塘关巡逻时,一不小心就会迷路哦!