每日一题:LeetCode-611. 有效三角形的个数

这篇具有很好参考价值的文章主要介绍了每日一题:LeetCode-611. 有效三角形的个数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

每日一题系列(day 14)

前言:

🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈

   🔎🔎如果说代码有灵魂,那么它的灵魂一定是👉👉算法👈👈,因此,想要写出💚优美的程序💚,核心算法是必不可少的,少年,你渴望力量吗😆😆,想掌握程序的灵魂吗❓❗️那么就必须踏上这样一条漫长的道路🏇🏇,我们要做的,就是斩妖除魔💥💥,打怪升级!💪💪当然切记不可😈走火入魔😈,每日打怪,拾取经验,终能成圣🙏🙏!开启我们今天的斩妖之旅吧!✈️✈️


题目:

  给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。

示例:

每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000

思路:

  根据题意,求满足称为三角形的三元组的对数,数组内有重复值也算,最简单的方法就是用暴力,三层for循环枚举出所有情况,第一层for控制i指向第一个数,第二层for循环控制j指向i的下一个位置,最后一层for循环k指向j的下一个元素,每层for循环都要保证小于数组的大小防止越界,最后根据两边之和大于第三边,随意将两个指针相加与第三个指针进行比较,如果大于计数+1,最后枚举出全部三元组。

代码实现:

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        int len = nums.size();
        int cnt = 0;
        for(int i = 0 ; i < len ; i++)
        {
            for(int j = i + 1; j < len ; j++)
            {
                for(int k = j + 1; k < len ; k++)
                {
                    if(nums[i] + nums[j] > nums[k])
                    {
                        cnt ++;
                    }
                }
            }
        }
        return cnt;
    }
};

每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法
每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法

  测试用例可以过,但是提交却过不了,这说明我们三层for循环时间复杂度 O(n^3) 还是太高了,我们可以想办法优化一下,三层for循环时间复杂度过高,那还有什么方法能够再优化一下呢?

  我们可以只使用两层for循环,这两层for循环和上面一样只是为了索引三角形的两条边,我们索引第三条边可以使用二分查找来查找第三个值,但是二分查找使用的前提是数组有序,所以在我们遍历数组之前,一定还要将数组进行排序,这样才能使用二分查找。
  同时,我们不能确定数组里面的元素是否全为0,这样也是不能构成三角形的,或者数组里面的前N位是0,后面又不是0这种,所以我们在开始操作之前,使用循环将i的指向的位置为非0位置。

代码实现:

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        int len = nums.size();
        if(len < 3) return 0;
        sort(nums.begin(), nums.end());

        int i = 0;
        while(!nums[i]) i++;
        
        int ret = 0;
        for(; i < len ; i++)
        {
            for(int j = i + 1 ; j < len ; j++)
            {
                int left = j, right = len;
                int mid = 0;
                while(left < right)
                {
                    mid = (right + left)/2;
                    if(nums[mid] < nums[i] + nums[j])  left = mid + 1;
                    else right = mid;
                } 
                ret += (left - j - 1);
            }
        }
        return ret;
    }
};

每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法

  我们就可以通过了,这样时间复杂度就降低到 O(logn * n^2) 了,但是我们发现这样时间复杂度还是有些高了。其实还有一种双指针解法更加高效巧妙且灵活。


思路:

  使用双指针解法,首先将数组排序,将最大元素设为比较元素,即最后一个元素是比较元素,设置left指针指向数组的0位置处,right指针指向比较元素前一个位置,这就是初始状态了。

每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法

  这时左指针与右指针指向的值相加与比较值进行比较,我们发现,nums[left]+nums[right]>nums[nums.size() - 1]的,然而数组又是有序数组,既然0位置处与右指针的值相加要大于比较值,那么在[left,right]这段区间内,左指针向右指针靠拢时,左右指针的和一定是要大于比较值的,所以符合题意的三元组就是right-left组了,我们可以在外部设置ret变量来接收这个值。
  9这个位置的值已经枚举完了,那么我们将right指针向左走一步,重复上述步骤,但是如果当nums[left]+nums[right]<nums[nums.size()-1]时,我们就要移动左指针了,如果当两指针相遇时还没有大于比较值的数,那么左边的情况也不需要再枚举了,因为递增数组1,最大的两个数相加都没有大于比较值,更何况比他们要小的值,所以当两指针相遇时,以当前比较值为基准的情况已经全部枚举完成。
  那么这个比较值就要向前移动一位,然后再重复上述步骤,直到比较值将nums[2]这个位置的值枚举完(因为三角形最低要三条边),整个数组符合条件的三元组就被我们记录下来了。

每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法

代码实现:

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());//保证数组有序
        int ret = 0;
        int n = nums.size() - 1;
        for(int i = n ; i >= 2 ; i--)//这层for循环表示比较值的位置
        {
            int left = 0, right = i - 1;
            while(left < right)
            {
                if(nums[left] + nums[right] > nums[i])
                {
                    ret += right - left;
                    right--;
                }
                else
                {
                    left++;
                }
            }
        }
        return ret;//返回三元组的个数
    }
};

每日一题:LeetCode-611. 有效三角形的个数,每日一题,leetcode,算法


  三种解题方式,暴力方法最为直接,也最容易想得到,在此基础上将暴力优化,第三层for循环改为二分查,并不是很容易想得到。第三种双指针是更难想了,本质上是将一个值固定不变,让两个指针分别代表三角形的两条边与这个固定值比较,比较是否构成三角形,再利用单调性的性质,将时间复杂度大大缩短。文章来源地址https://www.toymoban.com/news/detail-789665.html

到了这里,关于每日一题:LeetCode-611. 有效三角形的个数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【编程题】有效三角形的个数

    给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。 示例1: 输入: nums = [2,2,3,4] 输出: 3 **解释:**有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使用第二个 2) 2,2,3 示例2: 输入: nums = [4,2,3,4] 输出: 4 构成三角形的条件 :任意两条边之和大于第三边,其

    2024年02月11日
    浏览(37)
  • 「优选算法刷题」:有效三角形的个数

    给定一个包含非负整数的数组  nums  ,返回其中可以组成三角形三条边的三元组个数。 示例 1: 示例 2: 这道题,有一点挺新鲜的:构成三角形的三条边,仅需满足 2 条最短边之和大于等于第三条边即可。 以前的罗根,就总是傻傻地求 3 次😭 今天这道题,算是又打开了我新世

    2024年01月20日
    浏览(28)
  • 双指针算法实例5(有效三角形的个数)

    给定一个包含非负整数的数组  nums  ,返回其中可以组成三角形三条边的三元组个数。 示例 1: 示例 2: 提示: 1 = nums.length = 1000 0 = nums[i] = 1000 三角形构成条件:任意两边之和一定要大于第三边 其实在判断中,只需要判断 最小的两边和大于最长的一边 即可 假设 a=b=c 若要构成

    2024年02月11日
    浏览(34)
  • 【算法专题突破】双指针 - 有效三角形的个数(5)

    目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后: 题目链接:611. 有效三角形的个数 - 力扣(Leetcode)  我们可以根据示例1来理解这一道题目, 他说数组里面的数可以组成三角形三条边的个数, 那我们先自己枚举一下所有情况看看:  【2, 2, 3】  【2, 2, 4】  【2,

    2024年02月10日
    浏览(34)
  • AcWing 898. 数字三角形 (每日一题)

    像数组下标 出现 i-1 的,在循环的时候从 i=1 开始。 0x3f3f3f3f : 1061109567 Integer.MAX_VALUE : 2147483647 在选用 Integer.MAX_VALUE 时,很可能会出现 数据溢出 。 所以在用 Integer.MAX_VALUE 时 需要先取 MAX 再加 a[i][j]; 注:做 数字三角形 这题时, 初始化时需要注意一下边界 。 由于我们 状态计

    2024年02月11日
    浏览(30)
  • 【C语言每日一题】08. 字符三角形

    题目来源:http://noi.openjudge.cn/ch0101/08 总时间限制: 1000ms 内存限制: 65536kB 给定一个字符,用它构造一个底边长5个字符,高3个字符的等腰字符三角形。 输入只有一行, 包含一个字符。 该字符构成的等腰三角形,底边长5个字符,高3个字符。

    2024年02月10日
    浏览(27)
  • 【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字

       611. 有效三角形的个数 https://leetcode.cn/problems/valid-triangle-number/ 给定一个包含非负整数的数组  nums  ,返回其中可以组成三角形三条边的三元组个数。 本题是一个关于三角形是否能成立的题目,首先我们假设三角形的三边(a,b,c),我们要保证两边之和大于第三边    题

    2024年02月12日
    浏览(38)
  • Leetcode-976. 三角形的最大周长

    题目: 给定由一些正数(代表长度)组成的数组  nums  ,返回  由其中三个长度组成的、 面积不为零 的三角形的最大周长  。如果不能形成任何面积不为零的三角形,返回  0 。 示例 1: 示例 2: 提示: 3 = nums.length = 10^4 1 = nums[i] = 10^6 我一开始以为先排序,然后移动窗口

    2024年02月19日
    浏览(31)
  • C/C++每日一练(20230314) 移动数组元素、搜索二维矩阵、三角形最小路径和

    目录 1. 移动数组中的元素 2. 搜索二维矩阵 3. 三角形最小路径和 🌟 每日一练刷题专栏 🌟 Golang 每日一练 专栏 C/C++ 每日一练 ​专栏 Python 每日一练 专栏 Java 每日一练 专栏 将一维数组中的元素循环左移 k 个位置 输入: 第 1 行是一维数组元素的个数 n (数组大小) 第 2 行是

    2024年02月13日
    浏览(31)
  • 每日一练26&&27——变态跳台阶&&快到碗里来&&不用加减乘除做加法&&三角形

    题目链接: 这个题目很容易理解,但公式推导有些麻烦 假定第一次跳的是1阶,那么 剩下 的是n-1个台阶,跳法是f(n-1); 假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2); 假定第一次跳的是3阶,那么剩下的是n-3个台阶,跳法是f(n-3) … 假定第一次跳的是n-1阶,那

    2023年04月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包