当前位置: 首页 > ai >正文

专题一_双指针_有效三角形的个数

一:题目解析

题目链接:611. 有效三角形的个数 - 力扣(LeetCode)

解析:任意两边之和大于第三边 or 任意两边之差小于第三边,所以选择任意一个条件即可,只需满足a+b>c 和 a+c>b 和 b+c>a 即可

二:算法讲解

①:暴力

暴力无非就是三层for循环,加判断函数,伪代码如下:

for(i=O;i<n;i++)//固定第一个数
for(j=i+1;j<n;j++)//固定第二个数
for(k=j + 1;k<n; k++)//固定第三个数
check(nums[i],nums[j] ,nums[k] )//函数判断是否能构成三角形

解析:时间复杂度为:3N^3也就是N^3,会超时!

Q:为什么前面有3

A:因为check这一步每次进入都要执行三次(三次比较a+b>c ; a+c>b ;b+c>a) 

②:优秀

所以对暴力进行优化一下!

优化1:升序对比较的优化

现在有abc,我们排升序后,得到a<=b<=c,此时仅仅需要取较小的两个数字 a b 
去判断a+b>c 即可,一但成立,则一定为三角形!

因为:如果a+b>c ,那么a+c>b 和 b+c>a这两个式子恒成立!c本来就大于b或a,还给c加上一个数,所以这两个式子是一定成立的 !!

所以我们排序之后 只需比较一次即可!此时的时间复杂度为:NlogN(排序) + N^3

优化2:升序对三层循环的优化

形成有序后,我们可以对暴力中的三层for循环进行优化! 让其的复杂度更低!
假设现在是:[2,2,3,4,5,9,10 ],a(left) = 2;b(right) =9;c = 10,其中ab为两个指针,c先固定为最大的数字!

此时如果a+b>c了,此时不仅abc已经是有效三角形了,且我们a就不用再往后遍历到b的前一个了(a为2,3,4,5不用再遍历)!因为a+b 肯定都会>c(b在增加,肯定更能满足a+b>c)
所以我们的left指针不用移动,而是right指针从9变为5!

Q:为什么b从9变成5了 A:因为9的有效三元组全部收录!此时应该改变right指针,再去和left相加比较
此时2+5<10了,所以你的b也没必要向内枚举了(b只会越来越小);而是让a向内枚举,直到遇到和b相加>c的时候!

此时的时间复杂度为:NlogN(排序) +N^2(双指针遍历)

总结:先将数组排序,让复杂度从N^3 变为了 NlogN+N^2

三:代码编写

class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(), nums.end());int ret = 0;//存储有效三元组的个数int n = nums.size();for (int c = n - 1; c >= 2; c--) {//c从最后一个遍历到第三个元素 因为三元组 你起码得给ab留两个吧int left = 0, right = c - 1;//确定双指针的位置while (left < right) {//双指针相遇 代表此趟的c已经判断完成 c--后 双指针再次遍历if (nums[left] + nums[right] > nums[c]) {//a+b>c 则a不用再遍历了ret += right - left;//双指针下标之差代表有效三元组的个数 让ret+=即可right--;//然后right--} elseleft++;///a+b不>c  则left++ 才有可能a+b>c}}return ret;}
};

解释:

1:c从最后一个遍历到第三个元素,因为三元组,你c最多只能移动到第三个元素,这样才能留两个值给双指针

2:当a+b>c的时候,此时双指针下标之差代表有效三元组的个数,本质是bc不变,a的可变值的种数

http://www.xdnf.cn/news/14922.html

相关文章:

  • 【Linux | 网络】socket编程 - 使用TCP实现服务端向客户端提供简单的服务
  • 通过Tcl脚本命令:set_param labtools.auto_update_hardware 0
  • Spring Cloud服务注册与发现:架构设计与技术实践深度分析
  • VS Code侧边栏的“资源管理器找不到解决办法“、VScode重置视图位置/还原默认视图位置
  • Linux建立本地软件仓库
  • Spring Boot 扩展点深度解析:设计思想、实现细节与最佳实践
  • 【Oracle报错】[INS-13001] 环境不满足最低要求。
  • MySQL8.0基于GTID的组复制分布式集群的环境部署
  • Rust赋能美团云原生DevOps实践
  • uni-app uni-push 2.0推送图标不展示问题
  • 【HarmonyOS6】获取华为用户信息
  • 2025年人工智能、虚拟现实与交互设计国际学术会议
  • 客户端与服务端数据加密方案及实现
  • 1️⃣理解大语言模型
  • 深度学习——损失函数
  • 使用python 将多个docx文件合并为一个word
  • 电网的智能觉醒——人工智能重构能源生态的技术革命与公平悖论
  • vue3面试题(个人笔记)
  • 并发编程第一节
  • 首批 | 云轴科技ZStack加入施耐德电气技术本地化创新生态
  • Caffeine的tokenCache与Spring的CaffeineCacheManager缓存区别
  • 一文读懂动态规划:多种经典问题和思路
  • VScode SSH远程连接Ubuntu(通过SSH密钥对的方式)
  • 深度学习遇到的问题
  • C++如何进行性能优化?
  • qt绘制饼状图并实现点击即放大点击部分
  • 前端接收流式数据demo,并用markdown解析数据,包括EventSource和fetch两种方式
  • 前端交互自定义封装类:“双回调自定义信息弹窗”
  • 香港维尔利健康科技集团AI健康云平台通过国际信息安全认证,打造全球健康数据合规新标杆
  • Transformer-BiGRU、Transformer、CNN-BiGRU、BiGRU、CNN五模型回归预测对比,Matlab代码实现