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.mfbz.cn/a/597143.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NIO和NIO.2对比

Java NIO (New Input/Output) 是从Java 1.4版本开始引入的一个新的I/O API&#xff0c;用于替代原来的BIO&#xff08;Blocking I/O&#xff09;API。NIO提供了更加灵活和高效的网络通信方式&#xff0c;特别适合于高吞吐量的网络编程。NIO的主要特点是非阻塞模式&#xff0c;它…

数据结构(C):玩转顺序表

&#x1f37a;0.前言 &#x1f3b7;1.线性表 &#x1f3b8;2.顺序表 &#x1f4c0;动态顺序表的实现 &#x1f4bf;初始化 &#x1f4bf;检查容量是否满了&#xff0c;进行扩容 &#x1f4bf;插入&#xff1a;头插和尾插 &#x1f4bf;删除&#xff1a;头删和尾删 &…

Python实现2048游戏

提供学习或者毕业设计使用,功能基本都有,不能和市场上正式游戏相提比论,请理性对待! 在这篇博客中,我们将使用 Python 和 Pygame 库来编写经典的 2048 游戏。2048 是一个益智类游戏,通过在 4x4 网格上滑动方块并合并它们来创建一个新的数字,直到获得数字 2048 或者无法继…

bfs之走迷宫

文章目录 走迷宫广度优先遍历代码Java代码打印路径 走迷宫 给定一个 nm 的二维整数数组&#xff0c;用来表示一个迷宫&#xff0c;数组中只包含 0或 1&#xff0c;其中 0表示可以走的路&#xff0c;1表示不可通过的墙壁。 最初&#xff0c;有一个人位于左上角 (1,1) 处&#…

leetcode-岛屿数量-99

题目要求 思路 1.使用广度优先遍历&#xff0c;将数组中所有为1的元素遍历一遍&#xff0c;遍历过程中使用递归&#xff0c;讲该元素的上下左右四个方向的元素值也置为0 2.统计一共执行过多少次&#xff0c;次数就是岛屿数量 代码实现 class Solution { public:int solve(vec…

mac电脑如何安装python及环境搭建

&#xff08;1&#xff09;进入官网&#xff1a;Download Python | Python.org&#xff0c;根据自己电脑选择python (2)这里我选择的是mac,点击&#xff1a;macos&#xff0c;选择最近版本并点击进入 (3)选择mac版本&#xff1a; (4)点击就可以进入下载&#xff1a; (5)下载好之…

网站防御XSS攻击的有效策略与实施步骤

随着互联网应用的普及与发展&#xff0c;网站安全已成为众多企业关注的焦点&#xff0c;而XSS&#xff08;Cross-Site Scripting&#xff09;攻击作为最常见的Web安全漏洞之一&#xff0c;对用户数据安全构成严重威胁。本文将详细介绍网站如何有效防御XSS攻击&#xff0c;并提供…

Spring JdbcTemplate使用临时表+事务会话管理实现数据新增、查询及自动清除功能

需求描述&#xff1a; 由于某些情况下当查询过滤参数过大时&#xff0c;执行sql由于参数过大而报错&#xff0c;此时 需要使用临时表的方式&#xff0c;即 当参数超过某个阀值&#xff08;如 1000&#xff0c;可调整&#xff09;新增一张临时表&#xff0c;将原表 与 该临时表进…

2024精武杯部分复现

首先是计算机部分&#xff0c;这里是题目 做完才发现其实很多东西在火眼里面已经有更快的捷径了&#xff0c;但是自己当时没发现&#xff0c;还去傻傻的开虚拟机去找&#xff0c;说到底&#xff0c;还是对取证软件的理解不够&#xff0c;也不怎么会用。不废话了&#xff0c;直接…

怎么给word文件名批量替换部分文字?word设置批量替换文字教程

批量替换Word文件名中的几个字&#xff0c;对于经常处理大量文件的人来说&#xff0c;是一项非常实用的技能。以下是一个详细的步骤指南&#xff0c;帮助你快速完成这项任务。 首先&#xff0c;你需要准备一个可以批量重命名文件的工具。市面上有很多这样的工具可供选择&#x…

人工智能的发展将如何重塑网络安全

微信搜索关注公众号网络研究观&#xff0c;获取更多信息。 人们很容易认为人工智能 (AI) 真正出现是在 2019 年&#xff0c;当时 OpenAI 推出了 ChatGPT 的前身 GPT-2。 但现实却有些不同。人工智能的基础可以追溯到 1950 年&#xff0c;当时数学家艾伦图灵发表了题为“计算机…

密码学《图解密码技术》 记录学习 第十四章

目录 十四章 14.1 本章学习的内容 14.2 什么是 SSL/TLS 14.2.1 Alice 在 Bob 书店买书 14.2.2 客户端与服务器 14.2.3 АSSL/TLS 承载HTTP 14.2.4 SSL/TLS的工作 14.2.5 SSL/TLS也可以保护其他的协议 14.2.6 密码套件 14.2.7 SSL 与 TLS 的区别 14.3 使用 SSL/TLS 进…

产业观察:电机驱动成为人形机器人的动力核心

前不久&#xff0c;波士顿动力发布一则“再见&#xff0c;液压Atlas”视频&#xff0c;宣告其著名的液压驱动双足人形机器人Atlas正式退役。这则视频引起全球所有Atlas粉丝的高度关注。然而紧接着&#xff0c;波士顿动力便又推出了全部由电机驱动的新一代Atlas机器人&#xff0…

【Git】【MacOS】Github从创建与生成SSH公钥

创建账号 这一步不过多赘述&#xff0c;根据自己的邮箱新创建一个账号 配置SSH公钥 本人是macOS系统&#xff0c;首先从终端输入 cd ~/.ssh进入.ssh目录,然后通过 ls查看有没有一个叫做id_rsa.pub的文件 本人之前生成过SSH公钥,如果没有的话&#xff0c;通过 ssh-keygen -t…

luci框架相关笔记

luci架构 LuCI 架构采用了MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;各个目录的作用如下&#xff1a; model&#xff08;模型&#xff09;: 位于 /usr/lib/lua/luci/model 下&#xff0c;存放了与系统配置相关的模型脚本。这些脚本负责与底层系统…

cmd输入mysql -u root -p无法启动

问题分析&#xff1a;cmd输入mysql -u root -p无法启动 解决方法&#xff1a;配置系统环境变量 1.找到mysql安装文件下的bin文件&#xff1a;&#xff08;复制改文件地址,如下图所示&#xff09; 2.电脑桌面下方直接搜索环境变量并进入&#xff0c;如下图 3.点击环境变量&a…

读取打包到JAR中的文件:常见问题与解决方案(文件在但是报错not find)

读取打包到JAR中的文件&#xff1a;常见问题与解决方案 喝淡酒的时候&#xff0c;宜读李清照&#xff1b;喝甜酒时&#xff0c;宜读柳永&#xff1b;喝烈酒则大歌东坡词。其他如辛弃疾&#xff0c;应饮高梁小口&#xff1b;读放翁&#xff0c;应大口喝大曲&#xff1b;读李后主…

Python数据清洗与可视化实践:国际旅游收入数据分析

文章目录 概要整体流程名词解释NumPyPandasMatplotlibre 技术细节数据清洗可视化 小结 概要 在本篇博客中&#xff0c;我们将通过一个实际的案例&#xff0c;演示如何使用Python进行数据清洗和可视化&#xff0c;以分析国际旅游收入数据。我们将使用Python中的Pandas库来进行数…

04-25 周四 FastBuild重构实践-TLS、全局捕获异常、一键配置

04-25 周四 FastBuild重构实践 时间版本修改人描述04-25V0.1宋全恒新建文档2024年5月6日14:33:16V1.0宋全恒完成文档撰写 简介 由于 04-22 周日 阿里云-瑶光上部署FastBuild过程(配置TLS、自定义辅助命令)描述了重新部署一个FastBuild实例的过程&#xff0c;通过阅读这个&…

线性表的概念与结构,以及顺序表和链表的简单概念

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…
最新文章