【优选算法】双指针专项:1.移动零 2. 复写零 3.快乐数

🔥小龙报:个人主页

🎬作者简介:C++研发,嵌入式,机器人,AI等方向学习者

❄️个人专栏:《优选算法》
永远相信美好的事情即将发生

文章目录


前言

双指针是数组算法中最经典、最高效的解题思想之一,广泛应用于数组重排、元素处理、环形判断等高频场景。本篇精选移动零、复写零、快乐数三道经典题目,由浅入深讲解双指针的分块遍历、逆向处理、快慢指针判环核心逻辑。通过原理剖析与完整代码实操,帮助大家吃透双指针思维,夯实算法基础,熟练掌握数组类题目的通用解题思路。


一、移动零

1.1题目

链接:移动零

1.2 算法原理

核心思想: 数组分块 --- 双指针

划分的区域情况:

遍历过程中遇到的两种情况:

1.3 代码

cpp 复制代码
class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
        int dest = -1;
        for(int cur = 0;cur < nums.size();cur++)
        {
            if(nums[cur]) //扫描到非0
                swap(nums[++dest],nums[cur]);

        }
        
    }
};

二、复写零

2.1 题目

链接:复写零

2.2 算法原理

1.先找到最后一个复写的数

2.从后往前完成复写操作

i. 判断 cur 位置的值:

1.如果是 0 : dest 以及 dest - 1 位置修改成 0 , dest -= 2 ;

  1. 如果非零: dest 位置修改成 0 , dest -= 1 ;

ii. cur-- ,复写下一个位置。

2.3 代码

cpp 复制代码
class Solution 
{
public:
    void duplicateZeros(vector<int>& arr) 
    {
        //1.寻找复写的最后一个元素
        int cur = 0,dest = -1,n = arr.size();
        while(cur < n)
        {
            if(arr[cur]) //非0
                dest++;
            else
                dest+= 2;
            if(dest >= n - 1)
                break;
            cur++;
        }

         //处理特殊情况
        if(dest == n)
        {
            arr[n - 1] = 0;
            cur--;
            dest -= 2;
        }
         while(cur >= 0)
         {
            if(arr[cur])
                arr[dest--] = arr[cur--];
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--; 
            }
         }



    }
      
};

三、快乐数

3.1 题目

链接:快乐数

3.2 算法原理

问题分析

对于以个正整数,每⼀次将该数替换为它每个位置上的数字的平方和」这一个

操作记为 x 操作;题目告诉我们,当我们不断重复 x 操作的时候,计算以一定会死循环,死循环的方式式有两种:

▪ 情况一:一直在 1 中死循环,即 1 -> 1 -> 1 -> 1...

▪ 情况二:在历史的数据中死循环,但始终变不到 1

由于上述两种情况只会出现一种,因此,只要我们能确定循环是在「情况一」中进行,还是在「情况二」中进行,就能得到结果。

故模型简化为:在带环链表里判断相遇情况

简单证明

a. 经过⼀次变化之后的最大值 9^2 * 10 = 810 ( 2^31-1=2147483647 。选一个更大的最大 9999999999 ),也就是变化的区间在 1, 810 之间;

b. 根据「鸽巢原理」,一个数变化 811 次之后,必然会形成一个循环;

c. 因此,变化的过程最终会走到一个圈,因此可以用「快慢指针」来解决。

解法(快慢指针)

算法思路:

根据上述的题目分析,我们可以知道,当重复执行 x 的时候,数据会陷入到⼀个「循环」之中。而「快慢指针」有⼀个特性,就是在⼀个圆圈中,快指针总是会追上慢指针的,也就是说他们总会相遇在一个位置上。如果相遇位置的值是 1 ,那么这个数⼀定是快乐数;如果相遇位置不是 1的话,那么就不是快乐数。

3.3 代码

c 复制代码
class Solution {
public:
    //计算平方和
    int Sum(int n)
    {
        int sum = 0;
        while(n)
        {
            int t = n % 10;
            sum += t * t;
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) 
    {
        int slow = n,fast = Sum(n);
        while(slow != fast)
        {
            slow = Sum(slow);
            fast = Sum(Sum(fast));
        }
        return slow == 1;
    }
};

总结与每日励志

✨本次学习的三道题目,覆盖了双指针的核心用法:移动零利用前后指针实现数组原地分块,复写零通过逆向双指针规避数据覆盖问题,快乐数借助快慢指针巧妙解决循环判环难题。三道题层层递进,从数组基础操作到数学环形问题,充分体现了双指针高效、低空间复杂度的优势。熟练掌握这类思想,能够大幅提升代码解题效率,适配笔试面试各类算法场景。算法学习从无捷径,所有熟练的代码、通透的思路,都是日复一日积累的结果。不必畏惧难题,不必焦虑进度,每一次敲写代码、每一次复盘原理,都是在悄悄沉淀实力。编程路上,慢慢来,稳一点,坚持深耕、持续精进,所有付出都会化作突破自我的底气,终会遇见更好的自己。

相关推荐
AC赳赳老秦21 小时前
OpenClaw + 飞书多维表格:自动同步数据、生成统计图表、触发自动化任务
java·大数据·python·缓存·自动化·deepseek·openclaw
WangN221 小时前
【通识】RSL-RL快速上手
人工智能·python·机器学习·机器人
北域码匠21 小时前
奇偶归并排序:并行计算的排序利器
数据结构·算法·c#·排序算法
geovindu21 小时前
python: Reactor Pattern
开发语言·python·设计模式·反应器模式
1024+21 小时前
在 ‌Ubuntu 24.04‌ 上安装 ‌Python 3.8‌
linux·python·ubuntu
我不是懒洋洋21 小时前
从零实现一个消息队列:生产消费与持久化
c++
财经资讯数据_灵砚智能21 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年6月15日
大数据·人工智能·python·信息可视化·自然语言处理
CS_SKILL21 小时前
吉比特 C++ 实习一面面经:一轮把 C++、容器、并发、排序和网络全扫了一遍
java·开发语言·校招面经·实习面经·技术面经·吉比特校招
成都易yisdong21 小时前
上海某平面坐标系与CGCS2000坐标互转详解(含全域拟合点、实战案例、保密规范)
大数据·人工智能·算法
某林21221 小时前
从 Isaac Lab API 踩坑到硬件 MVP 的全链路实战破局
python·机器人·人机交互·ros2