目录
五. 有效三角形的个数(medium)
题目链接:有效三角形的个数
解法:
代码:
六:和为 s 的两个数字(easy)
题目链接:和为 s 的两个数字
解法:
代码;
七:三数之和(medium)
解法:
代码:
八:四数之和(medium)
题目链接:四数之和
解法:
代码:
五. 有效三角形的个数(medium)
题目链接:有效三角形的个数

解法:
思路一:(暴力求解)(会超时):
三层 for 循环枚举出所有的三元组,并且判断是否能构成三⻆形。
伪代码:


思路二 (排序+双指针):
因为判断三角形是否构成只需要看三个边长的最小的两个边加起来是否大于第三边即可。
因为题目给的数组是无序的所以我们需要先对数组进行排序,排序之后就利用 「对撞指针」去解决此问题。
设最长边枚举到 i 位置,区间 [left, right] 是 i 位置左边的区间(也就是比它小的区间):
如果 nums[left] + nums[right] > nums[i] :
- 说明 [left, right - 1] 区间上的所有元素均可以与 nums[right] 构成比nums[i] ⼤的⼆元组
- 满足条件的有 right - left 种
- 此时 right 位置的元素的所有情况相当于全部考虑完毕, right-- ,进⼊下⼀轮判断
如果 nums[left] + nums[right] <= nums[i] :
- 说明 left 位置的元素是不可能与 [left + 1, right] 位置上的元素构成满⾜条件的⼆元组
- left 位置的元素可以舍去, left++ 进⼊下轮循环
通过这种方式直到两个指针相遇结束我们就可以统计出固定10的情况下可以构成的三角形个数。
然后我们依次再从大到小固定数字再重复上面的步骤我们最终就可以得可以构成的·三角形总数。
时间复杂度
代码:
六:和为 s 的两个数字(easy)
题目链接:和为 s 的两个数字
解法:
方法1(暴力解法,会超时):
两层 for 循环列出所有两个数字的组合,判断是否等于⽬标值。
- 外层 for 循环依次枚举第⼀个数 a ;
- 内层 for 循环依次枚举第⼆个数 b ,让它与 a 匹配;
- 然后将挑选的两个数相加,判断是否符合目标值
伪代码:
方法二(双指针 - 对撞指针):
注意到本题是升序的数组,因此可以⽤「对撞指针」优化时间复杂度。

代码;
七:三数之和(medium)
题目链接: 三数之和

解法:
因为题目要求不能包含重复的三元组
例如这里就存在2个重复的三元组,所以我们求出需要去重
方法1(排序+暴力枚举+利用set去重):
算法复杂度为O(n^3),这里就不实现暴力了
方法二(排序+双指针):
- 先排序;
- 然后固定⼀个数 a :(a<=0)
- 在这个数后⾯的区间内,使⽤「双指针算法」快速找到两个数之和等于 -a 即可。
细节问题:这道题⾥⾯需要有「去重」操作
- 找到⼀个结果之后, left 和 right 指针要「跳过重复」的元素;(避免越界)
- 当使⽤完⼀次双指针算法之后,固定的 a 也要「跳过重复」的元素(避免越界)
接着连续固定数字再重复上述操作即可(因为已经排序过所以固定的值如果是正数就不能能找到符合题意的三元组,因此固定的值<=0)
代码:
八:四数之和(medium)
题目链接:四数之和
解法:
方法一(排序+暴力枚举+利用set去重):
方法二(双指针 - 对撞指针):
解决方法其实和上题三数之和差不多
- 依次固定⼀个数 a ;
- 在这个数 a 的后⾯区间上,利⽤「三数之和」找到三个数,使这三个数的和等于 target - a 即可。