大厂面试真题详解:三角形计数

简介: 大厂面试真题详解:三角形计数

给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形?

在线评测地址:领扣题库官网

样例 1:

输入: [3, 4, 6, 7]
输出: 3
解释:
可以组成的是 (3, 4, 6), 
           (3, 6, 7),
           (4, 6, 7)
样例 2:
输入: [4, 4, 4, 4]
输出: 4
解释:
任何三个数都可以构成三角形
所以答案为 C(3, 4) = 4

题目理解

  • 我们先考虑“三条边能构成三角形”的充分必要条件。我们首先想到的是“三角形的任意两边之和大于第三边,三角形的任意两边之差小于第三边”。如果从这个角度理解,代码编写比较麻烦,因为“任意”二字就要求我们去检验各种组合。
  • 如果我们仔细分析一下这个条件,就不难证明它等效于“较短的两边之和大于最长边”。对于升序排列的三个数[a, b, c],我们只需判断a + b > c是否成立,就知道它们是否能构成三角形。

解题思路

  • 最直观的方法是暴力法,三重循环枚举,时间复杂度为O(n^3)。
  • 如果先将数组排好序,二重循环固定较短两边a和b,然后再利用二分查找找到最大的满足a + b > c的c,这样可以将时间复杂度优化至O(n^2logn)
  • 这里我们采用双指针方法,可以继续降低时间复杂度。首先固定最大边的位置 i,然后在 [0, i-1]之间利用双指针找到满足条件的三边。时间复杂度为O(n^2)。

算法流程

  • 首先对数组进行升序排列。
  • 从右向左遍历最大边,固定最大边的位置i

    • 建立双指针left和right,初始分别指向0和i-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),只需占用常量空间。
public class Solution {
    /**
     * @param S: A list of integers
     * @return: An integer
     */
    public int triangleCount(int[] S) {
        int res = 0;
        int left = 0, right = S.length - 1;
        // 先对S进行排序
        Arrays.sort(S);
        // 最大边从右向左遍历
        for (int i = 0; i < S.length; i++) {
            // 建立双指针
            left = 0;
            right = i - 1;
            while (left < right) {
                // 可以构成三角形
                if (S[left] + S[right] > S[i]) {
                    res += (right - left);
                    right --;
                }
                // 不能构成三角形
                else {
                    left ++;
                }
            }
        }
        return res;
    }
}

更多题解参考:九章官网solution

相关文章
|
7月前
|
算法 Java
【面试题精讲】JVM-详细说说引用计数法的缺点-循环依赖
【面试题精讲】JVM-详细说说引用计数法的缺点-循环依赖
|
5天前
|
SQL 数据挖掘 数据处理
「SQL面试题库」 No_37 判断三角形
「SQL面试题库」 No_37 判断三角形
|
9月前
|
前端开发
经典面试题:如何使用CSS画一个三角形?
经典面试题:如何使用CSS画一个三角形?
51 0
|
安全 测试技术 Python
软件测试面试题及答案,这个题库有3千多道最新面试真题可以刷
相信对于很多软件测试新手来说,技术项目的面试是十分让人头疼的,生怕没回答得好,就会跟这个offer失之交臂
156 0
|
Serverless C语言 索引
华为面试C语言真题(二)
华为面试C语言真题( 二)
266 1
华为面试C语言真题(二)
|
设计模式 缓存 算法
腾讯Java高级岗180道面试真题,面试大厂拿45Koffer没问题!
一、数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度。 · 用Java写一个冒泡排序算法 · 描述一下链式存储结构。 · 如何遍历一棵二叉树? · 倒排一个LinkedList。 · 用Java写一个递归遍历目录下面的所有文件
|
消息中间件 NoSQL 网络协议
字节跳动三面Java经历,砍下年薪50W的Offer,面试真题整理分享
应广大读者要求,今天开更一些大厂的面经和相关的面试干货,下面这份**最新字节跳动春招面经+笔记**带给大家。
122 0
字节跳动三面Java经历,砍下年薪50W的Offer,面试真题整理分享
|
存储 自然语言处理 前端开发
【牛客刷题】大厂真题 | 前端面试篇(一)
【牛客刷题】大厂真题 | 前端面试篇(一)
166 0
|
人工智能 Java 测试技术
【牛客刷题系列】Java工程师 | 百度面试真题(二)
【牛客刷题系列】Java工程师 | 百度面试真题(二)
106 0