力扣-有效三角形的个数

1.题目描述

2.题目链接

611. 有效三角形的个数 - 力扣(LeetCode)

3.题目代码

java 复制代码
class Solution {
    public int triangleNumber(int[] nums) {
        //先排序
        Arrays.sort(nums);
        //若a<=b<=c,三角形条件可以优化为:a+b>c
        int temp=nums.length-1,sum=0;
        while(temp>1){
            int left=0,right=temp-1;
            while(left<right){
            if(nums[left]+nums[right]>nums[temp]){
                sum+=right-left;
                right--;
            }
            else {
                left++;
            }
            }
             temp--;
        }
        return sum;
    }
}

4.解题思路

1.有效三角形的条件

首先,我们要知道三角形形成的条件是:任意两边和大于第三边,也就是:

对于三条边长 a、b、c(假设 a≤b≤c),构成三角形需满足以下三个不等式同时成立:

  1. a+b>c
  2. a+c>b
  3. b+c>a

但是,我们可以先对数组进行排序,保证a<=b<=c,此时构成三角形的条件只需要满足:a+b>=c,因为c本身就大于a和b,所以c加上a或者b一定大于另一个数,2和3也就天然成立。

2.双指针和定数

这道题我们可以使用双指针和定数来解决

首先,定义 一个定数temp让temp指向数组的最后一个元素,也就是temp=nums【nums.length-1】。

定义两个指针left和right分别让它们指向剩下数组的最左边和最右边,也就是left=0,right=temp=nums.length。

3.结合单调性移动双指针

1).nums【left】+nums【right】>nums【temp】,这时构成三角形 ,而且因为left和right 分别是剩下数组的最左边和最右边 ,所以nums【left】和nums【right】也就是剩下数组的最小值和最大值

所以left到right之间的数,加上nums【right】 都大于nums【left】>nums【right】>nums**【temp】** 。也就是说,从left下标到right-1下标的数字,和right下标的数都可以构成三角形

所以我们直接让结果sum+=right-left

然后移动指针,让right指针左移,也就是right--。

2).nums【left】+nums【right】<=nums【temp】,因为nums【right】已经是剩下数组的最大值了,想要让不等式左边值变大满足三角形条件,就是需要nums【left】变大,也就是右移left指针,让left++。

直到left和right相遇,循环结束。此时我们改变temp定值,使temp左移一位。

5.代码细节

1)可以使用Arrays.sort(nums);来先对数组进行排序,这在很多题目里面非常重要。

java 复制代码
Arrays.sort(nums);

2)因为left和right的定义是剩余数组的边界,所以left和right应该是随着temp的改变不断改变的,所以left和right应该定义在temp循环内部。

java 复制代码
 while(temp>1){
            int left=0,right=temp-1;
            while(left<right){
            if(nums[left]+nums[right]>nums[temp]){
                sum+=right-left;
                right--;
            }
            else {
                left++;
            }
            }
             temp--;
        }

3)temp的while循环结束条件是temp>1,因为此时temp在数组第二个元素,他的左边只有1个元素,不可能构成三角形。

相关推荐
草履虫建模17 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq19 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq20 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
爱吃rabbit的mq20 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
(❁´◡`❁)Jimmy(❁´◡`❁)21 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi21 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
不能隔夜的咖喱1 天前
牛客网刷题(2)
java·开发语言·算法
VT.馒头1 天前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
进击的小头1 天前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
咖丨喱1 天前
IP校验和算法解析与实现
网络·tcp/ip·算法