欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Leetcode每日一题:976.largest-perimeter-triangle(三角形的最大周长)

程序员文章站 2024-02-21 14:19:16
...

Leetcode每日一题:976.largest-perimeter-triangle(三角形的最大周长)
思路:首先肯定是排序,排序后只需要从一个方向上开始找即可;但这里我用的二分查找,确定A[i]和A[i-1]后我们需要在后面找一个数x,使得x为<A[i]+A[i+1]的最大的数,所以这种东西秒想到二分查找;后来通过后看评论,排序后直接从数组尾部开始遍历即可,因为要找最大的周长,并且A[i]肯定是>(A[i-1]-A[i-2])的,所以只需要找到某个A[i],它能够满足A[i]<A[i-1]+A[i-2]即直接就是最大的周长;
Leetcode每日一题:976.largest-perimeter-triangle(三角形的最大周长)
速度还有有差别的

//法1:
//在a[l]和a[r]之间找到小于等于max的最大的值
int find(vector<int> &a, int l, int r, int max)
{
    if (l > r)
        return -1;
    if (a[l] > max)
        return -1;
    if (a[r] < max)
        return a[r];
    int pre = -1;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (a[mid] == max)
        {
            return a[mid];
        }
        else if (a[mid] < max)
        {
            //说明绕圈了,这个值就是目标值
            if (pre == a[mid])
            {
                return a[mid];
            }
            pre = a[mid];
            l = mid;
        }
        else
        {
            pre = a[mid];
            r = mid;
        }
    }
    return a[l];
}

static bool cmp(int a, int b)
{
    return a < b;
}

int largestPerimeter(vector<int> &A)
{
    int len = A.size();
    if (len < 3)
        return 0;
    int res = 0;
    sort(A.begin(), A.end(), cmp);
    for (int i = 1; i < len; i++)
    {
        int min = A[i] - A[i - 1];
        int max = A[i] + A[i - 1];
        int tar = find(A, i + 1, len - 1, max - 1);
        if (tar == -1)
        {
            continue;
        }
        if (res < max + tar)
        {
            res = max + tar;
        }
    }
    return res;
}

//法2:直接从尾端查找
    int largestPerimeter(vector<int>& A) {
        sort(A.begin(), A.end());
        for (int i = A.size() - 1; i >= 2; --i) {
            if (A[i] < A[i - 1] + A[i - 2]) {
                return A[i] + A[i - 1] + A[i - 2];
            }
        }
        return 0;
    }