跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

双指针算法实战:快乐数与盛水最多容器解析

双指针算法实战:快乐数问题通过快慢指针检测数字平方和运算是否进入循环,若最终收敛于 1 则为快乐数。盛水最多容器问题利用左右对撞指针,每次移动较短边以尝试寻找更大面积,避免暴力枚举超时。两者均体现了双指针在优化时间复杂度上的核心作用,配合 C++ 实现可高效解决此类经典面试题。

MongoKing发布于 2026/3/16更新于 2026/7/1861 浏览
双指针算法实战:快乐数与盛水最多容器解析

双指针算法实战:快乐数与盛水最多容器

03. 快乐数

题目描述: 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果这个过程结果为 1,那么这个数就是快乐数。

思路拆解: 为了方便叙述,我们将「计算各位数字平方和」这一操作记为 x。不断重复 x 操作时,结果只有两种走向:要么收敛到 1,要么陷入死循环。

这里有个关键观察:经过多次变换后,数值范围其实很小(最大不会超过 9^2 * 10 = 810)。根据鸽巢原理,变化过程必然会在有限步内形成循环。既然存在环,我们就可以用「快慢指针」来检测。

核心逻辑:

  • 快指针每次走两步,慢指针每次走一步。
  • 如果最终相遇在 1,说明是快乐数。
  • 如果相遇在其他位置,说明陷入了非 1 的循环,不是快乐数。

辅助函数实现: 我们需要一个函数来计算 n 的各位数字平方和。逻辑很简单:取模提取个位,累加平方,整除去掉个位,循环直到 n 为 0。

class Solution {
public:
    // 计算各位数字的平方和
    int bitsum(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;
        int fast = bitsum(n);
        
        // 快慢指针寻找循环点
        while (slow != fast) {
            slow = bitsum(slow);          // 慢指针走一步
            fast = bitsum(bitsum(fast));  // 快指针走两步
        }
        
        return slow == 1; // 判断相遇点是否为 1
    }
};

04. 盛水最多的容器

题目描述: 给定一个长度为 n 的整数数组 height。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

暴力解法陷阱: 虽然可以用双重循环枚举所有组合,但时间复杂度是 O(n^2),数据量大时会超时。我们需要更优的策略。

对撞指针策略: 设左右指针 left 和 right 分别指向数组首尾。容器的面积由宽度和较短边的高度决定: Area = min(height[left], height[right]) * (right - left)

为什么移动短边? 假设当前左边界小于右边界。此时高度由左边决定。如果我们固定左边,移动右边,宽度减小,且新的高度受限于原来的短边(或更小),面积必然变小。所以,想要获得更大的面积,必须尝试移动那个限制高度的短边,看看能否遇到更高的柱子。

算法流程:

  1. 初始化左右指针及最大面积变量。
  2. 当 left < right 时循环:
    • 计算当前面积并更新最大值。
    • 比较两边高度,移动较短的一边指针。
  3. 返回记录的最大面积。
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0;
        int right = height.size() - 1;
        int ret = 0;
        
        while (left < right) {
            // 计算当前容积
            int v = min(height[left], height[right]) * (right - left);
            ret = max(ret, v);
            
            // 移动较短的边
            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }
        return ret;
    }
};

这两道题都是双指针的经典应用。快乐数侧重于利用快慢指针检测链表式循环,而盛水容器则展示了如何通过贪心策略配合对撞指针将复杂度从 O(n^2) 降至 O(n)。掌握这两种模式,能帮你快速解决大量类似的面试题型。

目录

  1. 双指针算法实战:快乐数与盛水最多容器
  2. 03. 快乐数
  3. 04. 盛水最多的容器
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 2026 春晚机器人行业观察:流量博弈与落地挑战
  • Spring Boot 日志全方位指南:最佳实践与配置详解
  • Python 学习指南:核心优势与应用场景解析
  • 零基础学习 AI:大模型技术原理与应用入门
  • 实战指南:如何设计去AI味的Prompt提升AIGC内容质量
  • C++手写AVL树:插入、旋转与自平衡验证
  • 全球老龄化背景下的智能护理机器人发展研究
  • OpenClaw Gateway 服务运维:启动、停止与监控实践
  • Gitea 本地部署与常用 Git 命令实战指南
  • 基于 Java SSM 框架的线上学习网站设计与实现
  • FaceFusion AI 换脸工具本地部署与使用指南
  • Python 并发编程实战:多线程与多进程详解
  • Visual C++ 运行库故障诊断与修复指南
  • Linux/C++进阶:man 手册、GDB 调试与静态动态库详解
  • Flutter 三方库 whatsapp_bot_flutter 在鸿蒙系统的适配与实战指南
  • 前端国际化实战指南:构建全球化应用
  • Go 语言命令行 AI 对话客户端开发与部署实战
  • DeepSeek-OCR-WebUI 部署指南:支持 7 种识别模式与 GPU 加速
  • 青少年软件编程 Python 等级考试一级解析
  • Spring IoC 容器与依赖注入核心机制详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online