初探算法之双指针开篇

初探算法之双指针开篇

目录

前言:

此篇作为算法篇章的首篇文章,自然得简单说上几句。算法部分呢,多刷题是必不可少的。从暴力解法过渡到算法解法,过程着实有些艰辛,而算法的思考尤为关键。所以算法部分的讲解大多借助题目直接展开,以题目来传授算法知识。鉴于每个人对算法的接受程度有别,每篇通常涵盖两题左右,难题部分一般只设一道,且题目均取自LeetCode,本文会以最优解法来阐释不同的算法,通过题目解析、算法原理、算法编写这三个部分来解决问题。

双指针算法

题目一:

示例如下:

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

题目解析:
给定一个数组,需要将其中的0移动到数组末尾,同时无需考虑0的相对顺序,但要保留非零元素的相对顺序。若不使用双指针,有诸多解法,例如把所有非零元素移到开头,不过每移动一次得遍历一次,时间复杂度接近O(N²),这属于暴力解法。那该如何运用双指针呢?

算法原理:
借助双指针可将数组划分成三个区域:[0,dest]为非零元素区域,[dest,cur]是0元素区域,[cur,end]是未遍历区域。双指针并非传统意义上的指针,而是一种形象的指向概念。这里借助数组下标来定义两个指针。起始时二者均从0开始,dest初始可先不明确,cur遍历数组,遇到非零元素时,将其放到dest位置,具体操作是dest从-1开始,找到非零元素后,dest先自增,再与cur位置元素交换,cur继续往后遍历。

算法编写:

class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
        for(int cur = 0,dest = -1;cur < nums.size();cur++)
        {
            if(nums[cur])
            swap(nums[++dest],nums[cur]);
        }
    }
};

简单分析时间复杂度,此为一次遍历,时间复杂度为O(N),相较暴力解法有显著优化。

题目链接:283. 移动零 - 力扣(LeetCode)

题目二:

示例如下:

输入: n = 19
输出: true
解释: 1² + 9² = 82
8² + 2² = 68
6² + 8² = 100
1² + 0² + 0² = 1

题目解析:
题目叫做快乐数,来瞧瞧它有多“快乐”。快乐数的定义是:将一个数的每一位数字的平方相加,多次操作后若能得到1,那这个数就是快乐数;若一直循环却无法得到1,就不是快乐数。这类题目没有暴力解法,因为暴力的话很可能陷入死循环出不来,所以直接进入算法原理部分。

算法原理:
我们可以通过画图来看看变化情况。以19为例,经过4次变化得到1;而2经过多次变化后,会出现和第一次变化相同的值4。可以理解为2在变化时形成了一个环,且数的变化无法跳出这个环,所以不是快乐数。那19是否也有环呢?换个角度想,19变化时会不会形成一个仅包含1的环呢?此时大家应该明白了,我们可以用两个指针,一个走得快,一个走得慢,它们必定会相遇,相遇时判断是否为1即可。那为什么一定会出现环呢?这就要用到鸽巢原理了。LeetCode中给出了n的最大取值,我们考虑最大情况,比如10个9组成的数,计算其一次变化后的值为810,所以变化后的值最大不超过810。定义函数F(x)表示一次变化,那么一个数经过811次变化会产生811个数,但可能的取值区间只有810个,根据鸽巢原理,必然有重复的数,也就形成了环。

算法编写:

class Solution 
{
public:
    int _isHappy(int num)
    {
        int ans = 0,sum = 0;
        while(num)
        {
            sum = num % 10;
            ans = ans + sum * sum;
            num /= 10;
        }
        return ans;
    }
    bool isHappy(int n) 
    {
        int slow = n,fast = n;
        while(1)
        {
            slow = _isHappy(slow);
            fast = _isHappy(_isHappy(fast));
            if(slow == fast)
            {
                if(slow == 1)
                return true;
                else
                return false;
            }
        }
    }
};

今日算法分享至此,感谢阅读!

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/13683.html

赞 (0)
LomuLomu
上一篇 2025 年 9 月 20 日
下一篇 2025 年 9 月 20 日

相关推荐

  • Claude Pro微信支付宝代充流程

    国内用户如何开通Claude Pro?本文整理Claude充值、Claude代充、微信支付宝付款和Organization ID确认流程。

    未分类 2026 年 6 月 4 日
    24200
  • IDEA2025.3激活教学

    重要声明:本文所涉及的 IDEA 破解补丁及激活码资源均来源于网络收集,仅限个人学习研究使用,严禁用于任何商业用途。若资源存在侵权问题,请联系作者删除。条件允许的话,强烈推荐大家购买 JetBrains 官方正版授权! 作为 JetBrains 旗下最负盛名的开发工具,IntelliJ IDEA 凭借其强大的智能编码辅助功能,成为众多开发者的首选 IDE。本…

    IDEA破解教程 2026 年 2 月 2 日
    49100
  • ChatGPT Plus订阅开通会员详细操作教程

    是否能用国内方式开通,关键要看充值渠道是否支持本人账号。面对缺少微信或支付宝付款入口,需要快速理解代码的产品经理若希望继续进行代码片段阅读与思路定位,可以用微信或支付宝购买卡密,然后在自助页面确认自己的账号。流程并不复杂,但每一步都应围绕同一个登录账号进行,尤其不要在获取账号信息前临时切换邮箱或浏览器身份。

    未分类 2026 年 8 月 27 日
    7300
  • IntelliJ IDEA 最新激活码 2025.3 专用

    2024最新IDEA破解教程:永久激活JetBrains全家桶至2099年(含PyCharm/DataGrip激活码) 本指南兼容IDEA、PyCharm、DataGrip、Goland等JetBrains系列开发工具,全家桶版本通用! 话不多说,先展示最新版IDEA破解成功的界面截图,可以看到有效期已激活至2099年,非常给力! 下面,我将通过详细的图文步…

    IDEA破解教程 2025 年 12 月 30 日
    58100
  • idea激活码免费通用版+全新idea破解教程下载

    本教程适用于 IDEA、PyCharm、DataGrip、Goland 等,支持 Jetbrains 全家桶! 废话少说,先上图:最新版 IDEA 已顺利激活至 2099 年,爽翻! 接下来,我将用图文手把手带你完成 IDEA 的永久激活,老版本同样适用。 无论你用的是 Windows、macOS 还是 Linux,我都已把对应文件打包整理好了。 下载 ID…

    IDEA破解教程 2025 年 11 月 10 日
    32600

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信