[leetcode/lintcode 题解] Google面试题:三角形计数

给定一个整数数组,在该数组中,寻找三个数,分别表明三角形三条边的长度,问,能够寻找到多少组这样的三个数来组成三角形?
 
在线评测地址:领扣题库官网
 
 
样例 1:
样例 2:
题目理解
  • 咱们先考虑“三条边能构成三角形”的充分必要条件。咱们首先想到的是“三角形的任意两边之和大于第三边,三角形的任意两边之差小于第三边”。若是从这个角度理解,代码编写比较麻烦,由于“任意”二字就要求咱们去检验各类组合。
  • 若是咱们仔细分析一下这个条件,就不难证实它等效于“较短的两边之和大于最长边”。对于升序排列的三个数[a, b, c],咱们只需判断a + b > c是否成立,就知道它们是否能构成三角形。
解题思路
  • 最直观的方法是暴力法,三重循环枚举,时间复杂度为O(n^3)。
  • 若是先将数组排好序,二重循环固定较短两边ab,而后再利用二分查找找到最大的知足a + b > cc,这样能够将时间复杂度优化至O(n^2logn)
  • 这里咱们采用双指针方法,能够继续下降时间复杂度。首先固定最大边的位置 i,而后在 [0, i-1]之间利用双指针找到知足条件的三边。时间复杂度为O(n^2)。
算法流程
  • 首先对数组进行升序排列。
  • 从右向左遍历最大边,固定最大边的位置i
    • 创建双指针leftright,初始分别指向0i-1
    • 若是S[left] + S[right] > S[i],说明三者能够构成三角形。与此同时,最小边的索引为left+1, left+2,...,right-1时,都能与S[right]S[i]构成三角形。因此知足条件的三角形找到了right-left个。而后right指针左移进入下一轮。
    • 若是S[left] + S[right] <= S[i],说明不能构成三角形。left指针右移进入下一轮。
复杂度分析
  • 时间复杂度为O(n^2)。外层遍历最大边是n,内层循环移动双指针是n,因此总复杂度为O(n^2)。
  • 空间复杂度为O(1),只需占用常量空间。
 
更多题解参考:九章官网solution
相关文章
相关标签/搜索