🌈个人主页: Aileen_0v0
🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法
💫个人格言:“没有罗马,那就自己创造罗马~”
双指针算法
移动零
- 两个指针的作用:
cur
: 从左到右扫描遍历数组,将区间分成已处理区间和待处理区间(cur
指向的是处理过的最后一个元素)。dest
: 将已处理区间分成:非零元素区间和零元素区间(dest
指针指向的是非0元素的最后一个位置)。
- 通过这两个指针我们可以将整个数组细分为3个区间:非零,零,待处理(它们的区间可划分为:
[0,dest]
,[dest+1 , cur - 1]
,[cur , n - 1]
),假设数组总长为n,那么整个数组下标从头到尾是[0,n-1]
。- 遍历数组的三个状态:
- 开始状态:
- 由于数组还未遍历所以
cur
这个指针在下标0处。 - 还未遍历,那么非零区间应该无元素,我们可以将其放置在下标位 -1 的位置处。
- 此时,整个区间
[0,n-1]
都还是待处理区间。
- 由于数组还未遍历所以
- 遍历阶段的两种状态:
- 当cur遇到0时,满足目的区间要求,所以无需进行任何操作,继续往下遍历即可,即:
cur++
。
- 当cur遇到0时,满足目的区间要求,所以无需进行任何操作,继续往下遍历即可,即:
- 当cur遇到非0时,需要先将该元素与前面的零元素交换位置,即交换
[dest + 1 , cur ]
,然后让这两个指针分别移动(即:dest++,cur++),从而满足目的区间要求。
- 当cur遇到非0时,需要先将该元素与前面的零元素交换位置,即交换
- 结束状态:
- 整个区间就划分成题目要求的非零和零区间,并且非零区间按照相对顺序排好,而待处理区间消失,此时(cur = n)。
- 开始状态:
- 遍历数组的三个状态:
Java代码实现
- tips:交换操作可以通过定义中间变量来操作。
class Solution {
public void moveZeroes(int[] nums) {
for(int cur = 0 , dest = -1 ; cur < nums.length ; cur++){
if(nums[cur] != 0){
dest++;
int temp = nums[cur];
nums[cur] = nums[dest];
nums[dest] = temp;
}
}
}
}
Python代码实现
class Solution(object):
def moveZeroes(self, nums):
dest= - 1
for cur in range (len(nums)):
if nums[cur] != 0 :
dest += 1
nums[dest] , nums[cur] = nums[cur] , nums[dest]
import java.util.Random;
public class FarewellMessageGenerator {
public static void main(String[] args) {
String[] greetings = {
"祝您前程似锦 ✨",
"愿您心想事成 🌟",
"祝您幸福安康 ❤️",
"愿您天天开心 😊",
"祝您事业腾飞 🚀"
};
String[] emojis = {
"🎉", "🌈", "🌻", "🍀", "🎊"
};
Random random = new Random();
String message = greetings[random.nextInt(greetings.length)];
String emoji = emojis[random.nextInt(emojis.length)];
System.out.println(message + " " + emoji);
System.out.println("感谢阅读!希望这篇文章对您有所帮助 🙏");
}
}
文章总结
核心思想
通过双指针(cur
和dest
)将数组划分为三个逻辑区间:非零区、零区和待处理区。cur
扫描数组,dest
标记非零元素边界,动态交换元素实现零元素后移。
关键步骤
- 初始化:
dest
置为-1,表示非零区初始为空;cur
从0开始遍历。 - 非零处理:遇到非零元素时,与
dest+1
位置交换,两指针同步右移。 - 零跳过:遇到零时仅移动
cur
,保持非零区紧凑性。
应用价值
该算法是双指针技术的经典案例,适用于元素分类、去重等问题,提升代码效率的同时培养分治思维。