[LeetCode有效三角形的个数(三角形计数)] | 刷题打卡

528 阅读2分钟

[LeetCode有效三角形的个数(三角形计数)] | 刷题打卡

第9题了,是不是以为终于不用看双指针题目了?No,这题依然是双指针!这题考察的是实际问题的抽象描述能力。

一直有刷题习惯,最近才看到掘金举办了刷题活动,特来参加!此题为第9题。不得不说掘金的主题就是漂亮呀!赞。

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述:

有效三角形的个数

描述

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

样例 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

二、思路分析:

方法
描述
时间复杂度
空间复杂度
双指针法相向双指针,利用两边之和大于最长边O(n2)O(n^2)(1)(1)
双指针法遍历数组元素[0,..i,...length-1] ,假设每一轮遍历,第i个就是最长边,找到两数之和大于nums[i]的个数O(n2)O(n^2)(1)(1)
双指针法[0,i]之中相向寻找,并求和O(n2)O(n^2)(1)(1)

三、AC 代码:


import java.lang.reflect.Array;
import java.util.Arrays;

/*
 * @lc app=leetcode.cn id=611 lang=java
 *
 * [611] 有效三角形的个数
 */

// @lc code=start
class Solution {
    public int triangleNumber(int[] nums) {
        if (nums == null || nums.length <= 1) {
            return 0;
        }
        int start = 0;
        int end = nums.length - 1;
        int ansCount = 0;
        Arrays.sort(nums);
        for (int i = 0; i < nums.length ; i++) {
            start = 0;
            end = i - 1;
            while (start < end) {
                if (nums[start] + nums[end] > nums[i]) {
                    ansCount += end - start;
                    end--;
                } else {
                    start++;
                }
            }
        }
        return ansCount;
    }
}
// @lc code=end

四、总结:

这道锻炼的是从题目中抽象出两数之和类的问题,可以当做是从第8题三数之和演变而来。为什么这样说呢?主要因为一点数学知识两边之和大于最长边,抽象描述为a+b>c

收获启发

  • 收获1:双指针时间复杂度不都是O(nlogn)的,也存在O(nlogn)的,也存在O(n^2)O(n^3)$
  • 收获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指针右移进入下一轮。