《双指针魔法:3分钟彻底掌握「移动零」的算法精髓》

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)
🌈个人主页: 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时,需要先将该元素与前面的零元素交换位置,即交换[dest + 1 , cur ],然后让这两个指针分别移动(即:dest++,cur++),从而满足目的区间要求。
      • 结束状态:
        • 整个区间就划分成题目要求的非零和零区间,并且非零区间按照相对顺序排好,而待处理区间消失,此时(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("感谢阅读!希望这篇文章对您有所帮助 🙏");
    }
}
 

文章总结

核心思想
通过双指针(curdest)将数组划分为三个逻辑区间:非零区、零区和待处理区。cur扫描数组,dest标记非零元素边界,动态交换元素实现零元素后移。

关键步骤

  • 初始化dest置为-1,表示非零区初始为空;cur从0开始遍历。
  • 非零处理:遇到非零元素时,与dest+1位置交换,两指针同步右移。
  • 零跳过:遇到零时仅移动cur,保持非零区紧凑性。

应用价值
该算法是双指针技术的经典案例,适用于元素分类、去重等问题,提升代码效率的同时培养分治思维。

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)
](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I'mAileen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值