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

C++ 双指针实战:有效三角形个数与和为 S 的两个数字

双指针技巧适用于有序数组问题。通过固定一边并使用对撞指针寻找满足条件的组合,可高效解决三角形计数及两数之和问题。核心在于排序后利用单调性减少遍历次数,将时间复杂度从 O(n^3) 或 O(n^2) 优化至 O(n^2) 或 O(n)。掌握此模式有助于进阶处理三数之和等复杂场景。

人间失格发布于 2026/2/22更新于 2026/9/1072 浏览
C++ 双指针实战:有效三角形个数与和为 S 的两个数字

C++ 双指针实战:有效三角形个数与和为 S 的两个数字

双指针是处理数组类问题的利器,尤其在有序数组中,利用单调性可以大幅降低时间复杂度。本文将通过两个经典题目——「有效三角形个数」和「和为 S 的两个数字」,深入剖析对撞指针的应用逻辑。

1. 有效三角形个数

1.1 题目描述

给定一个包含非负整数的数组 nums,返回其中能组成三角形的三元组个数。

1.2 思路分析

构成三角形的条件是任意两边之和大于第三边。对于三个数 a, b, c(假设已排序 a <= b <= c),只需满足 a + b > c 即可。

算法核心步骤如下:

  1. 排序:首先将数组升序排列。
  2. 固定最长边:从后往前遍历,固定最大的边 nums[k]。
  3. 双指针查找:在 [0, k-1] 区间内使用左右指针 left 和 right。
    • 若 nums[left] + nums[right] > nums[k],说明当前 right 与 left 到 right-1 之间的所有元素组合均满足条件(因为数组有序)。此时计数增加 right - left,并将 right 左移。
    • 若 nums[left] + nums[right] <= nums[k],说明两边之和太小,需增大较小的一边,将 left 右移。

1.3 代码实现

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end()); // 升序排序
        int n = nums.size();
        int ret = 0;
        
        // 从最大边开始遍历,至少需要三条边
        for (int i = n - 1; i >= 2; i--) {
            int left = 0, right = i - 1;
            while (left < right) {
                if (nums[left] + nums[right] > nums[i]) {
                    ret += right - left; // 累加符合条件的组合数
                    right--;
                } else {
                    left++; // 和太小,移动左指针
                }
            }
        }
        return ret;
    }
};

int main() {
    vector<int> nums1 = {4, 2, 3, 4};
    cout << Solution().triangleNumber(nums1) << endl;
    return 0;
}

双指针移动示意图

2. 和为 S 的两个数字

2.1 题目描述

给定一个升序排列的整数数组 price 和一个目标值 target,找出两个数使得它们的和等于目标值。如果存在多组解,返回任意一组;不存在则返回 {-1, -1}。

2.2 思路分析

由于输入数组已经是有序的,我们可以直接使用对撞指针:

  1. 初始化 left = 0,right = price.size() - 1。
  2. 计算 sum = price[left] + price[right]。
    • 若 sum > target,说明和太大,right 左移减小数值。
    • 若 sum < target,说明和太小,left 右移增大数值。
    • 若 sum == target,找到答案,直接返回。
  3. 循环直到 left >= right。

2.3 代码实现

#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        int left = 0;
        int right = price.size() - 1;
        
        while (left < right) {
            int sum = price[left] + price[right];
            if (sum > target) {
                right--;
            } else if (sum < target) {
                left++;
            } else {
                return {price[left], price[right]};
            }
        }
        return {-1, -1};
    }
};

int main() {
    vector<int> nums1 = {3, 9, 12, 15};
    vector<int> result = Solution().twoSum(nums1, 18);
    
    cout << "[";
    for (int i = 0; i < result.size(); i++) {
        cout << result[i];
        if (i < result.size() - 1) cout << ",";
    }
    cout << "]" << endl;
    return 0;
}

运行结果示意

总结

这两个问题展示了双指针在数学组合中的典型用法:排序预处理 + 指针智能移动。这种模式不仅解决了当前问题,也是后续学习「三数之和」、「四数之和」等进阶题目的基石。掌握这一思想,能帮助我们在面对复杂约束时快速找到最优解路径。

目录

  1. C++ 双指针实战:有效三角形个数与和为 S 的两个数字
  2. 1. 有效三角形个数
  3. 1.1 题目描述
  4. 1.2 思路分析
  5. 1.3 代码实现
  6. 2. 和为 S 的两个数字
  7. 2.1 题目描述
  8. 2.2 思路分析
  9. 2.3 代码实现
  10. 总结

更多推荐文章

查看全部
  • 黑客盗取密码的常见方法与防御策略
  • Clawdbot 整合 Qwen3-32B 本地部署与 Web 访问指南
  • Vheer:免费免登录的 AI 绘画与视频生成工具
  • 二分查找实战:山峰数组峰顶索引与寻找峰值
  • JadeAI:开源 AI 简历生成器,支持 50 套模板与 Docker 部署
  • C++ 线程库与多线程编程详解
  • VibeVoice 开源实践:构建小时级多角色语音合成系统
  • BoltzGen:MIT 开源生成式 AI 模型用于大分子 Binder 设计与安装
  • 2025 GitHub 趣味项目与学习资源精选
  • Robot Lab 基于 Isaac Lab 的机器人强化学习使用指南
  • Python YAML 模块实战:接口测试参数存储与配置管理
  • C++ STL list 容器详解:使用与模拟实现
  • AI 时代细胞生物学最新进展:从图像分析到虚拟细胞
  • 基于 Python 的阿布量化交易框架
  • OpenClaw 龙虾机器人免费部署与配置指南
  • WebMCP:Chrome 新 API 特性与 Agentic Web 前瞻
  • CentOS 7 环境下安装 JDK 1.8 及解决 wget 命令缺失问题
  • Trae x Vizro:低代码构建专业数据可视化仪表板的高效方案
  • 阿里开源 Page-Agent:一行 JS 代码实现大模型前端 DOM 控制
  • 基于SpringBoot2与Vue3的疫情打卡健康评测系统设计

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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