LeetCode 611. 有效三角形的个数

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

题目说,给定一个包含非负整数的数组 num,返回其中可以组成三角形三条边的三元组个数。

示例: nums = [4, 2, 3, 4];

有效组合如下:

2,3,4 (使用第一个4)

2,3,4 (使用第二个4)

2,4,4

3,4,4

做题思路:

可能想到的第一种方案就是暴力枚举,枚举出所有的情况,比如下面的代码: 

int sum = 0;
for (int i = 0; i < n; ++i)
{for (int j = i + 1; j < n; ++j){for (int k = j + 1; k < n; ++k){if (IsValid(v[i], v[j], v[k]))	++sum;}}
}

上面的暴力枚举的时间复杂度是 O(N^3)。 我们思考一下,能不能优化一下? 

优化一:判断 a,b,c 三个数字能否构成一个合法三角形

首先,如果数据不是有序的,那么判断需要通过三次,即:

  • a + b > c;
  • a + c > b;
  • b + c > a;

但如果此时数据是有序的,假如, a <= b <= c,那么此时判断能否构成一个合法三角形,只需要判断一次,即:

a + b > c

而 a + c > b 和 b + c > a 不需要判断,因为此时c是最大的数据,最大的数据加上一个非负数,一定大于另外的一个数据,比如,a + c 是一定大于 b 的。

这是优化一。

优化二,我们想通过双指针 + 单调性的方案优化上面的问题,通过一个示例来理解一下:

假设数据为2,3,4,6,6,7,9,让我们来判断一下可以构成三角形的个数:

首先,我们固定一个值,然后判断,剩下的数字和这个固定值能构成的三角形个数是多少,比如,我们固定最大值为9,然后判断剩下的数据和这个9能构成的三角形个数是多少个,如图所示:

 

因为此时 a = 2, b = 7, c = 9,它们是有序的数据,故只需要判断一次:a + b > c,不成立,既然最小的 a 不能构成一个三角形,那么就让a向右移动,如下:

此时 a = 3,b = 7,c = 9,同理,只需要判断一次,a + b > c , 成立,因为数据是有序的,而此时在 3 到 7 这个区间中,3 是最小的数据,那么4,6,6,毋庸置疑,也可以和 b = 7,c = 9 构成一个三角形, 故4,6,6, 不需要再判断,因此,当 c = 9,b = 7 时,能构成的三角形个数就等于b所在的下标 - a所在的下标,此时b = 7这种情况就讨论完了,因此,b 向左移动:

此时 a = 3, b = 6,c = 9, a + b > c,不成立,因此,a 向右移动:

a = 4, b = 6, c = 9,a + b > c,成立,因为在a到b这个区间中,a此时是最小的,而数据又是单调递增 (有序的),因此,在 a 和 b 中间的值就不需要再判断了,此时一定可以和 b = 6,c = 9 构成三角形,因此,此时可以构成三角形的个数:b的下标 - a 的下标,b向左移动。

此时,和上述情况一样,可以构成三角的个数:b的下标 - a的下标 ,b向左移动:

 

a 和 b 相遇,c = 9 这种情况能构成的三角形的个数就讨论完了。此时,我们在固定一个值,即让c向左移动,让 c == 7,然后重复上述过程,如下所示:

此时,我们就可以将一组数据可以构成三角型的个数全部讨论清楚,可以发现,上面这个思路的时间复杂度:O(N^2),因为c从最后一个数据开始,需要从后向前遍历数组(O(N)),而每一个c都需要让a和b一起遍历 (a向右移动,b向左移动) 数组,故也是O(N),因此上面算法的时间复杂度为 O(N^2),这就是通过单调性 + 双指针解决上述问题。

代码如下:

#include <iostream>
#include <vector>class Solution {
public:inline bool IsValid(int a, int b, int c){return a + b > c;}int triangleNumber(std::vector<int>& nums) {// 这里的 left 相当于a// 这里的 right 相当于b// 这里的 objpos 相当于c// 它们都是数组下标std::sort(nums.begin(), nums.end());int objpos = nums.size() - 1;int sum = 0;while (objpos > 1){int left = 0;int right = objpos - 1;while (left < right){if (IsValid(nums[left], nums[right], nums[objpos])){sum += (right - left);right--;}else{left++;}}objpos--; }return sum;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/675132.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MIT加州理工等革命性KAN破记录,发现数学定理碾压DeepMind!KAN论文解读

KAN的数学原理 如果f是有界域上的多元连续函数&#xff0c;那么f可以被写成关于单个变量和加法二元操作的连续函数的有限组合。更具体地说&#xff0c;对于光滑函数f&#xff1a;[0, 1]ⁿ → R&#xff0c;有 f ( x ) f ( x 1 , … , x n ) ∑ q 1 2 n 1 Φ q ∑ p 1 n …

华为机考入门python3--(23)牛客23- 删除字符串中出现次数最少的字符

分类&#xff1a;字符串 知识点&#xff1a; 访问字典中keychar的值&#xff0c;不存在则返回0 my_dict.get(char, 0) 字典的所有值 my_dict.value() 列表中的最小值 min(my_list) 题目来自【牛客】 import sysdef delete_min_freq_char(s):# 计算字母出现的频次…

streamlit通过子目录访问

运行命令&#xff1a; streamlit hello 系统默认使用8501端口启动服务&#xff1a; 如果想通过子目录访问服务&#xff0c;可以这么启动服务 streamlit hello --server.baseUrlPath "app" 也可以通过以下命令换端口 streamlit hello --server.port 9999 参考&…

网络安全--红队资源大合集

目录 相关资源列表 攻防测试手册 内网安全文档 学习靶场 工具包集合 内网安全文档 学习手册相关资源 产品设计文档 版本管理平台漏洞收集 相关工具拓展插件 Kali 环境下拓展插件 Nessus 相关工具拓展插件 Awvs 相关工具拓展插件 红队攻击的生命周期&#xff0c;…

就业班 第三阶段(redis) 2401--5.7 day2 redis2 哨兵(前提是做好了主从)+redis集群

1、设置密码&#xff08;redis&#xff09; 先在redis.conf里面找到这个 后面写上要设置的密码即可 2、哨兵模式 监控redis集群中master状态的的工具 在做了主从的前提下 主 从1 从2 作用 1)&#xff1a;Master状态检测 2)&#xff1a;如果Master异常&#xff0c;则会进行…

python中type,object,class 三者关系

type,object,class 三者关系 在python中&#xff0c;所有类的创建关系遵循&#xff1a; type -> int -> 1 type -> class -> obj例如&#xff1a; a 1 b "abc" print(type(1)) # <class int> 返回对象的类型 print(type(int)) …

FL Studio20.9水果安装及切换修改中文语言教程

前言 喜欢音乐制作的小伙伴千万不要错过这个功能强大&#xff0c;安装便捷的音乐软件哦&#xff01;如果你们已经下载好了这款软件的话&#xff0c;小编今天在这里就为大家详细讲解下如何安装FL Studio软件&#xff0c;一起来学习吧&#xff01; 注意&#xff1a; &#xff0…

力扣刷题--数组--第二天

今天仍然做二分查找相关的题目。先来回顾一下二分查找的方法和使用的条件。二分查找是在数组中查找目标值的一种方法&#xff0c;通过边界索引确定中间索引&#xff0c;判断中间索引处的元素值和目标值的大小&#xff0c;来不断缩小查找区间。使用二分查找有如下一些限制&#…

Windows系统安装MySQL数据库详细教程

【确认本地是否安装mysql】 &#xff08;1&#xff09;按【winr】快捷键打开运行&#xff1b; &#xff08;2&#xff09;输入services.msc&#xff0c;点击【确定】&#xff1b; &#xff08;3&#xff09;在打开的服务列表中查找mysql服务&#xff0c;如果没有mysql服务&am…

LMdeploy推理实践

在inter-studio平台上&#xff0c;下载模型&#xff0c;体验lmdeploy 下载模型 这里是因为平台上已经有了internlm2模型&#xff0c;所以建立一个符号链接指向它&#xff0c;没有重新下载 ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b /root/如…

Qt | QComboBox(组合框)

01、上节回顾 Qt 基础教程合集02、QComBox 一、QComboBox 类(下拉列表、组合框) 1、QComboBox 类是 QWidget 类的直接子类,该类实现了一个组合框 2、QComboBox 类中的属性 ①、count:const int 访问函数:int count() const; 获取组合框中的项目数量,默认情况下,对于空…

鸿蒙OpenHarmony南向:【Hi3516标准系统入门(IDE方式)】

Hi3516标准系统入门&#xff08;IDE方式&#xff09; 注意&#xff1a; 从3.2版本起&#xff0c;标准系统不再针对Hi3516DV300进行适配验证&#xff0c;建议您使用RK3568进行标准系统的设备开发。 如您仍然需要使用Hi3516DV300进行标准系统相关开发操作&#xff0c;则可能会出现…