点击蓝色“力扣加加”关注我哟

加个“星标”,带你揭开算法的神秘面纱!

这是力扣加加第「9」篇原创文章

题目地址(611. 有效三角形的个数)

https://leetcode-cn.com/problems/valid-triangle-number/

题目描述

给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。

示例 1:

输入: [2,2,3,4]输出: 3解释:有效的组合是:2,3,4 (使用第一个 2)2,3,4 (使用第二个 2)2,2,3注意:

数组长度不超过1000。数组里整数的范围为 [0, 1000]。

前置知识

  • 排序
  • 双指针
  • 二分法
  • 三角形边的关系

暴力法(超时)

思路

首先要有一个数学前提: 如果三条线段中任意两条的和都大于第三边,那么这三条线段可以组成一个三角形。即给定三个线段 a,b,c,如果满足 a + b > c and a + c > b and b + c > a,则线段 a,b,c 可以构成三角形,否则不可以。

力扣中有一些题目是需要一些数学前提的,不过这些数学前提都比较简单,一般不会超过高中数学知识,并且也不会特别复杂。一般都是小学初中知识即可。

如果你在面试中碰到不知道的数学前提,可以寻求面试官提示试试。

关键点解析

  • 三角形边的关系
  • 三层循环确定三个线段

代码

代码支持: Python

class Solution:    def is_triangle(self, a, b, c):        if a == 0 or b == 0 or c == 0: return False        if a + b > c and a + c > b and b + c > a: return True        return False    def triangleNumber(self, nums: List[int]) -> int:        n = len(nums)        ans = 0        for i in range(n - 2):            for j in range(i + 1, n - 1):                for k in range(j + 1, n):                    if self.is_triangle(nums[i], nums[j], nums[k]): ans += 1

        return ans

「复杂度分析」

  • 时间复杂度:,其中 N 为 数组长度。
  • 空间复杂度:

优化的暴力法

思路

暴力法的时间复杂度为 , 其中  最大为 1000。一般来说,  的算法在数据量 <= 500 是可以 AC 的。1000 的数量级则需要考虑  或者更好的解法。

OK,到这里了。我给大家一个干货。应该是其他博主不太会提的。原因可能是他们不知道, 也可能是他们觉得太小儿科不需要说。

  1. 由于前面我根据数据规模推测到到了解法的复杂度区间是 , ,不可能是  (WHY?)。
  2. 降低时间复杂度的方法主要有: 空间换时间 和 排序换时间(我们一般都是使用基于比较的排序方法)。而排序换时间仅仅在总体复杂度大于  才适用(原因不用多说了吧?)。

这里由于总体的时间复杂度是 ,因此我自然想到了排序换时间。当我们对 nums 进行一次排序之后,我发现:

  • is_triangle 函数有一些判断是无效的
    def is_triangle(self, a, b, c):        if a == 0 or b == 0 or c == 0: return False        # a + c > b 和  b + c > a 是无效的判断,因为恒成立        if a + b > c and a + c > b and b + c > a: return True        return False
  • 因此我们的目标变为找到a + b > c即可,因此第三层循环是可以提前退出的。
for i in range(n - 2):    for j in range(i + 1, n - 1):        k = j + 1        while k and num[i] + nums[j] > nums[k]:            k += 1        ans += k - j - 1
  • 这也仅仅是减枝而已,复杂度没有变化。通过进一步观察,发现 k 没有必要每次都从 j + 1 开始。而是从上次找到的 k 值开始就行。原因很简单, 当 nums[i] + nums[j] > nums[k] 时,我们想要找到下一个满足 nums[i] + nums[j] > nums[k] 的 新的 k 值,由于进行了排序,因此这个 k 肯定比之前的大(单调递增性),因此上一个 k 值之前的数都是无效的,可以跳过。
for i in range(n - 2):    k = i + 2    for j in range(i + 1, n - 1):        while k and nums[i] + nums[j] > nums[k]:            k += 1        ans += k - j - 1

由于 K 不会后退,因此最内层循环总共最多执行 N 次,因此总的时间复杂度为 。

这个复杂度分析有点像单调栈,大家可以结合起来理解。

关键点分析

  • 排序

代码

class Solution:    def triangleNumber(self, nums: List[int]) -> int:        n = len(nums)        ans = 0        nums.sort()        for i in range(n - 2):            if nums[i] == 0: continue            k = i + 2            for j in range(i + 1, n - 1):                while k and nums[i] + nums[j] > nums[k]:                    k += 1                ans += k - j - 1        return ans

「复杂度分析」

  • 时间复杂度:
  • 空间复杂度:取决于排序算法

更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。目前已经 30K star 啦。

关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。


点关注,不迷路。如果再给 ➕ 个星标就更棒啦!

推荐阅读

1、帅地给你总结了这份高频地算法解题技巧,助你更快速着解题!

2、你的衣服我扒了 - 《最长公共子序列》

3、从老鼠试毒问题来看二分法

4、我是如何刷LeetCode的?

5、帅地给你总结了这份高频地算法解题技巧,助你更快速着解题!

如果觉得文章不错,帮忙点个在看呗

判断三个数是否能构成三角形_【内含干货】611. 有效三角形的个数相关推荐

  1. 上面两点下面一个三角形_这种胖胖的圆角三角形,在PPT里居然有这么多种画法!...

    昨天,有设计师问到,如何用 PPT 绘制胖圆角三角形. 考虑到这是基础鼠绘技巧,而鼠绘又是很多动画与定制项目的基础. 所以,今天给大家分享一下绘制的思路,以后好空手造素材. 相信我,这是很多收费课程里 ...

  2. 用java判定三角形_八年级数学上册三角形知识点总结

    三角形的分类 三角形的内角和定理及推论 三角形的内角和定理:三角形三个内角和等于180°.推论:①直角三角形的两个锐角互余.②三角形的一个外角等于和它不相邻的来两个内角的和.③三角形的一个外角大于任何 ...

  3. 前端怎么画三角形_用CSS画一个三角形

    作者 | 李银城 三角形的场景很常见,打开一个页面可以看到各种各样的三角形: 由于div一般是四边形,要画个三角形并不是那么直观.你可以贴一张png,但是这种办法有点low,或者是用svg的形式,但是 ...

  4. 上面两点下面一个三角形_章勤琼:三角形内角和180该如何说明 ——小学数学中的合情推理和演绎推理...

    (以下内容全文转自<教学月刊(小学版)>2019年第11期58-61页"数说九章"专栏.参考文献方式:章勤琼, 杜娅茹.三角形内角和180°该如何说明--小学数学的合情 ...

  5. 给定一个区间寻找三角形_计算给定图片中的三角形数量–程序化解决方案

    给定一个区间寻找三角形 One of my friend sent me below image as puzzle to count the triangles. I started countin ...

  6. c++直角空心三角形_压轴题中对三角形中位线的另类诠释

    压轴题中对三角形中位线的另类诠释 关于三角形的中位线,定义是连接三角形两边中点的线段,性质是它平行于第三边且等于第三边的一半:判定方法是经过三角形一边中点且与第三边平行.在几何证明中,它的作用通常是构 ...

  7. 空间三角形_高考数学:一解三角形复习知识点,让你学得很简单

    通过对任意三角形边长和角度关系的探索,掌握正弦定理.余弦定理,并能解决一些简单的三角形度量问题: 高中数学必修内容中解三角形有着一席之地,要通过对任意三角形的边长和角之间的关系进行转换,就要用到正余弦 ...

  8. 空间三角形_快来围观这个三角形空间的巧妙利用

    泰国La Vela酒店 La Vela/Time Architecture 由专筑网王雪纯,李韧编译 来自建筑事务所的描述:泰国La Vela酒店是一个新开发项目,其中一共设置有181间客房.2间餐厅 ...

  9. css空心三角形_纯CSS制作空心三角形和实心三角形及其实现原理

    纯CSS制作空心三角形和实心三角形及其实现原理 在一次项目中需要使用到空心三角形,我瞬间懵逼了.查阅了一些资料加上自己的分析思考,终于是达到了效果,个人感觉制作三角形是使用频率很高的,因此记录下来,供 ...

  10. android shpe 三角形_在Android中制作三角形按钮

    有没有办法制作一个可以用作Android按钮的等腰三角形? 此按钮占据整个屏幕: 这是我当前的xml: android:layout_width="match_parent" an ...

最新文章

  1. poj3259(SPFA算法)
  2. 在MAC平台下使用Eclipse出现了中文乱码
  3. java gson 工具类_gson工具类将Java类转换为json的使用
  4. CCPC2019-湖南全国邀请赛(湘潭大学)
  5. 代理模式——HeadFirst设计模式学习笔记
  6. LeetCode MySQL 1741. 查找每个员工花费的总时间
  7. oracle如何设置权限,ORACLE的权限设置
  8. 快速了解云原生中的微服务应用(内含福利)
  9. C++_类和对象_对象特性_初始化列表---C++语言工作笔记045
  10. 给老板汇报技术规划的一些要点(转)
  11. 计算机硬盘的常用分区工具,常用的几款分区合并工具推荐,合理使用电脑硬盘...
  12. 内定抽奖小程序_Excel制作抽奖小程序,单人、多人抽奖只要三步就可实现
  13. 网页加速器1.0.5.6 免费版
  14. SAP Local WebIDE Access denied
  15. Ubuntu系统录屏webm格式mp4格式方法
  16. python安卓库拍照_Python Faker库的实战,用Faker库生成伪造的安卓通讯录
  17. 百度怎么上传个人信息,百度百科怎么创建自己呢?
  18. 十个1分钟换来健康,搞IT必看
  19. 老板!过年了来谈谈加薪吧!
  20. 使用docker部署zabbix,自定义微信报警

热门文章

  1. ASP.net报错汇总: This application is currently offline.
  2. 11-2-进程控制块
  3. Baidu-Rpc中Pb结构转为Json
  4. vue自定义组件递归实现树状_一道价值25k的腾讯递归组件面试题(Vue3 + TS 实现)...
  5. 吉大20春学期计算机系统结构在线作业一,吉大20春学期《计算机原理及系统结构》在线作业一【奥鹏百分答案】...
  6. proxool mysql 配置 useunicode_proxool + MySQL + servelt 的使用
  7. mysql的jar包文件在哪找_数据库的jar在哪找
  8. 2008 r2 server 提权_Windows UAC 本地提权(CVE-2019-1388)
  9. Python+OpenCV:Hough圆检测(Hough Circle Transform)
  10. HALCON: texture_laws用法解析