leetcode刷题:611.有效三角形的个数(双指针实现)

题目地址:有效三角形的个数


解决此题时,首先需要知道的是如何判断三个数字是否能够构成三角形。

我们知道,三角形任意两边之和都大于第三边。所以判断三个数字是否能构成三角形需要进行三次比较(最基础的思路)

方法一:暴力枚举

此题一个最容易想到的解法就是暴力遍历。即穷举法,列举出每一种可能的组合情况并进行判断。不难想到需要设置三重循环,时间复杂度是O(n^3)。但是这种方法可能会有超时的风险(也许使用C/C++能够侥幸通过,但如果使用python之类较慢的语言大概率无法通过)

方法二:双指针

上述我们已经给出了判断三个数是否构成三角形的方法,然而三次判断其实也比较繁琐,是否可以实现一次判断呢?

其实我们在数学学习中肯定知道一种方法,那就是判断三个数中较小的两个数之和与最大数的大小关系。因为只要最小的数加起来大于最大的数,那么这三个数无论如何组合,最后得到的结果肯定都是满足三角形的性质的。

因此我们就可以采取这样一种思想来设计算法。首先找到最大的数,然后对于剩余的数进行排列组合,判断它们的和是否大于最大的数。

为了找到最大的数,我们可以先将原数组进行升序排序。此时可以知道最大的数就在数组尾端。此时设置双指针,分别指向剩余数组中的最小数与最大数。通过操作双指针进行判断。

如何控制双指针的指向呢?我们可以以下列例子来简单模拟一下:

 

需要注意的是,max至少需要指向第三个元素(下标为2),因为至少需要三条边才能构成一个三角形。

采用双指针方法时间复杂度为O(n^2),相较于暴力解法有很大提升。

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int ret=0;
        int n=nums.size();
        for(int i=n-1;i>=2;i--)
        {
            int left=0,right=i-1;
            while(left<right)
            {
                if(nums[left]+nums[right]>nums[i])
                {
                    ret+=right-left;
                    right--;
                }
                else
                {
                    left++;
                }
            }
        }
        return ret;
    }
};

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值