【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++红黑树封装实战:从零实现MyMap与MySet

【C++:封装红黑树】C++红黑树封装实战:从零实现MyMap与MySet

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶、测试开发要点全知道 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的C++专栏简介: 目录 C++的两个参考文档 1  ~>  分析:源码及框架 1.1  见一见源码 1.2  对比set和map的源码:泛型编程的应用 2  ~>  map和set的模拟实现 2.1  实现出复用红黑树的框架(支持insert) 2.2  迭代器iterator的实现 2.3  迭代器iterator实现思路分析 2.

By Ne0inhk

Visual C++ 6.0中文版安装包下载教程及win11安装教程

本文分享的是Visual C++ 6.0(简称VC++6.0)中文版安装包下载及安装教程,关于win11系统下安装和使用VC++6.0使用问题解答,大家在安装使用的过程中会遇到不同的问题,如遇到解决不了的问题请给我留言! 一、安装包的下载 vc6.0安装包下载连接: https://pan.quark.cn/s/710dc0efe636 二、安装vc++6.0 1.鼠标右键解压到“VC++ 6.0”安装包,解压后如图所示: 2.双击Steup.exe,进行安装; 3.点击下一步 4.更改路径,建议不要安装在C盘(默认盘符),可以选择其他的盘符,点击浏览进行更改盘符。 5.选择C盘(默认盘或系统盘)以外的盘符。

By Ne0inhk
全网最全100道C++高频经典面试题及答案解析:C++程序员面试题库分类总结

全网最全100道C++高频经典面试题及答案解析:C++程序员面试题库分类总结

前言 C++作为一门兼具高性能与灵活性的语言,持续推动着量子计算、自动驾驶、区块链、AI编译器等领域的技术革命。本题库精选100道高频面试题,涵盖从内存模型、编译器内部机制到跨学科前沿应用的深度内容,专为资深工程师、系统架构师及科研岗位设计。无论是准备顶级科技公司面试,还是探索C++在安全关键系统(如航天、医疗)与新兴领域(如脑机接口、边缘AI)的工程实践,这些题目将帮助您展现对语言本质的理解和对复杂场景的掌控力。 题库特点: 垂直深入:超越语法层面,聚焦标准演进(C++20/23)、硬件协同优化及形式化验证等高级主题。 跨领域融合:结合LLVM/MLIR编译器开发、CUDA加速、实时操作系统等场景,体现C++的系统级控制能力。 第一部分:面向对象与内存管理(1-10题) 1. 虚函数实现原理(字节跳动/腾讯) 题目:虚函数表(vtable)在C++中是如何工作的?写出示例代码说明动态多态的实现。

By Ne0inhk

3.6-Web后端基础(java操作数据库)

目录 前言 JDBC 介绍 查询数据 需求 准备工作 代码实现 代码剖析 ResultSet 预编译SQL SQL注入 SQL注入解决 性能更高 增删改数据 需求 代码实现 Mybatis 介绍 快速入门 辅助配置 配置SQL提示 配置Mybatis日志输出 JDBC VS Mybatis 数据库连接池 介绍 产品 增删改查操作 删除 新增 修改 查询 XML映射配置 XML配置文件规范 XML配置文件实现 MybatisX的使用 SpringBoot配置文件 介绍 语法 案例 前言 在前面我们学习MySQL数据库时,都是利用图形化客户端工具(如:idea、datagrip),来操作数据库的。 我们做为后端程序开发人员,

By Ne0inhk