【C++】优选算法必修篇之双指针实战:有效三角形个数 & 和为s的两个数字

【C++】优选算法必修篇之双指针实战:有效三角形个数 & 和为s的两个数字
在这里插入图片描述

【C++】优选算法必修篇之双指针实战:有效三角形个数 & 和为s的两个数字


双指针应用场景

应用场景介绍----------<----------链接直达请点击


目录

1. 有效三角形个数

1.1 题目链接

题目链接直达<----------请点击

1.2 题目描述

在这里插入图片描述

1.3 题目示例

在这里插入图片描述

1.4 算法思路

  1. 我们首先得清除构成三角形的条件:两边之和大于第三边,两边之差小于第三边,但是要验证这两个条件好像很麻烦,有没有更简单的方法呢?
  2. 当三个数a,b,c我们从小到大排序:然后你会发现只需要满足a + b > c就能构成一个有效的三角形。
  3. 在排序后的数组中,我们固定最大的边 nums[k] 作为三角形的第三边,然后在 [0, k-1] 范围内使用对撞指针寻找满足条件的两边。
  • 具体来说,设置 left = 0right = k-1。当 nums[left] + nums[right] > nums[k] 时,由于数组是升序排列,leftright-1 的所有位置与当前 right 组成的配对都能满足条件。这时我们可以直接给计数器增加 right - left 个有效组合,然后将 right 左移一位。
  • 如果 nums[left] + nums[right] <= nums[k],说明当前的两边之和太小,需要增大其中一边。由于 right 已经是当前范围内较大的值,我们通过将 left 右移来增加两边之和。

1.5 核心代码

#include<iostream>#include<vector>#include<algorithm>usingnamespace std;classSolution{public:inttriangleNumber(vector<int>& nums){sort(nums.begin(), nums.end());//升序排序int n = nums.size();//n为数组大小int ret =0;for(int i = n -1; i >=2; i--)//因为最少三条边,所以i>=2{int left =0, right = i -1;while(left < right){if(nums[left]+ nums[right]> nums[i]){ ret += right - left; right--;}else{ left++;}}}return ret;}};

1.6 示例测试(总代码)

#include<iostream>#include<vector>#include<algorithm>usingnamespace std;classSolution{public:inttriangleNumber(vector<int>& nums){sort(nums.begin(), nums.end());//升序排序int n = nums.size();//n为数组大小int ret =0;for(int i = n -1; i >=2; i--)//因为最少三条边,所以i>=2{int left =0, right = i -1;while(left < right){if(nums[left]+ nums[right]> nums[i]){ ret += right - left; right--;}else{ left++;}}}return ret;}};intmain(){ vector<int> nums1 ={4,2,3,4}; cout <<Solution().triangleNumber(nums1)<< endl;return0;}
在这里插入图片描述

2. 和为s的两个数字

2.1 题目链接

题目链接直达<----------请点击

2.2 题目描述

在这里插入图片描述

2.3 题目示例

在这里插入图片描述

2.4 算法思路

  1. 因为这个数组题目中已经说明是升序了,我们可以同样可以采用对撞指针来实现。
  2. 一个指向第一个数据,一个指向最后一个数据,然后让他们相加。如果结果大于traget说明过大,right–;如果结果小于traget说明太小,left++;如果相等就返回,直到left和right指向同一个位置循环停止。

2.5 核心代码

//有效三角形个数,和为s的两个数字#include<iostream>#include<vector>usingnamespace std;classSolution{public: vector<int>twoSum(vector<int>& price,int target){int left =0;int right = price.size()-1;while(left < right){if(price[left]+ price[right]> target){ right--;}elseif(price[left]+ price[right]< target){ left++;}else{return{ price[left],price[right]};//等价于vector<int> ans;//ans.push_back(price[left]);//ans.push_back(price[right]);//return ans;}}return{-1,-1};}};

2.6 示例测试(总代码)

//有效三角形个数,和为s的两个数字#include<iostream>#include<vector>#include<algorithm>usingnamespace std;classSolution{public: vector<int>twoSum(vector<int>& price,int target){int left =0;int right = price.size()-1;while(left < right){if(price[left]+ price[right]> target){ right--;}elseif(price[left]+ price[right]< target){ left++;}else{return{ price[left],price[right]};//等价于vector<int> ans;//ans.push_back(price[left]);//ans.push_back(price[right]);//return ans;}}return{-1,-1};}};intmain(){ vector<int> nums1 ={3,9,12,15}; vector<int> result =Solution().twoSum(nums1,18);// 正确输出vector的方式 cout <<"[";for(int i =0; i < result.size(); i++){ cout << result[i];if(i < result.size()-1){ cout <<",";}} cout <<"]"<< endl;return0;}
在这里插入图片描述

总结

在掌握了双指针基础模型(快慢指针、对撞指针)之后,我们进一步探索双指针在数学组合问题中的精妙应用。本篇通过「有效三角形个数」和「和为s的两个数字」两个经典问题。

掌握了这些基础模型后,我们可以进一步挑战:

🔢 三数之和 —— 在二维对撞基础上增加一维遍历,处理更复杂的组合约束
🔢 四数之和 —— 双层循环+对撞指针的组合应用,展现分治思想的威力
🎯 最接近的三数之和 —— 引入差值最小化的优化目标,拓展双指针的适用边界

这些进阶问题都建立在本文所述的核心思想之上——排序预处理 + 指针智能移动,体现了算法设计中"分而治之"的经典智慧。


下一篇,我们将深入探索多指针的高阶应用:
【C++】优选算法必修篇之双指针实战:三数之和 & 四数之和

Read more

千面之法: 释放 C++ 多态的灵活威力

千面之法: 释放 C++ 多态的灵活威力

目录 1:多态的概念 1.1:概念 2.多态的定义与实现 2.1:多态的构成条件 2.2:虚函数 2.3:虚函数的重写 2.3.1:虚函数重写的两个例外 2.3.1.1:协变(基类与派生类函数的返回值不同,基类虚函数返回基类对象的指针或引用,派生类虚函数返回派生类对象的指针或引用时) 2.3.1.2:析构函数的重写 2.4:C++11 override和final 2.4.1:final关键字 2.4.2:override关键字 2.5:重载、

By Ne0inhk

Python 爬虫项目:爬取 B 站视频标题与播放量

前言 B 站(哔哩哔哩)作为国内领先的视频内容平台,其视频标题、播放量等数据是分析内容趋势、用户偏好的重要依据。相较于静态网页爬取,B 站页面融合了动态加载等特性,对新手而言是进阶爬虫学习的典型场景。本文从零基础视角出发,系统讲解如何构建稳定的 B 站视频数据爬虫,涵盖动态页面分析、数据精准提取、反爬策略适配等核心知识点,帮助读者掌握针对主流视频平台的爬虫开发思路。 摘要 本文以B 站热门视频榜单(https://www.bilibili.com/v/popular/rank/all)为爬取目标,采用 requests 库发送 HTTP 请求获取页面源码,通过 BeautifulSoup 解析 HTML 结构,精准提取视频标题、播放量、UP 主、弹幕数等核心数据,并实现数据的结构化存储与可视化展示。针对 B

By Ne0inhk

Trae编译C++

一、前置准备 1. 安装 Trae: * 下载对应系统版本(Windows/Linux/macOS),解压到自定义目录(如D:\trae); * 配置环境变量(将 Trae 的可执行文件路径加入系统PATH),确保终端 / 命令行能直接输入trae调用。 2. 确认依赖:Trae 依赖 GCC/Clang,需先安装: * Windows:安装 MinGW(推荐 MinGW-w64),配置gcc环境变量; * Linux:sudo apt install gcc g++(Debian/Ubuntu); * macOS:xcode-select --install安装 Xcode 命令行工具。 二、用 Trae 编译 C++ 的核心步骤(

By Ne0inhk

MISRA C++静态分析集成CI/CD:项目应用示例

将MISRA C++静态分析融入CI/CD:一位嵌入式工程师的实战手记 最近在参与一个车载ECU模块的开发,团队面临的最大挑战不是功能实现,而是如何确保每一行代码都经得起功能安全标准ISO 26262的严苛审查。我们最终选择将 MISRA C++ 静态分析深度集成到CI/CD流程中——这不仅是一次工具链升级,更是一场从“写完再检”到“边写边防”的工程思维转变。 今天我想以这个真实项目为例,和你聊聊我们是如何一步步把这套看似“教条”的编码规范,变成流水线里沉默却可靠的“守门人”的。 为什么是MISRA C++?不只是合规,更是系统确定性的基石 如果你做过汽车电子、工业控制或航空航天类项目,大概率听说过 MISRA(Motor Industry Software Reliability Association) 。它最初由英国汽车工业界发起,目标很明确: 让C/C++这种强大但危险的语言,在关键系统中变得可控、可预测。 而 MISRA C+

By Ne0inhk