专题一 -双指针 - leetcode 611. 有效三角形的个数 | 中等难度

在这里插入图片描述

leetcode 611. 有效三角形的个数 | 中等难度

1. 题目详情

给定一个包含非负整数的数组 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

提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000

1. 原题链接

leetcode 611. 有效三角形的个数

2. 基础框架

● Cpp代码框架

class Solution {
public:
    int triangleNumber(vector<int>& nums) {

    }
};

2. 解题思路

1. 题目分析

( 1 ) (1) (1) 题目要求数组nums中所有的满足构成三角形的三个数的组合个数。
( 2 ) (2) (2) 对于a/b/c三边,构成三角形的条件是任意两边之和大于第三边:
a+b>c&&a+c>b&&b+c>a

2. 算法原理

( 1 ) (1) (1) 首先呢先想到暴力解法:三层for循环依次确定三个边a/b/c,并判断a+b>c&&a+c>b&&b+c>a,都满足了计数才自增;时间复杂度O(n^3),直接提交leetcode不给过。
进行优化:先对数组nums排序,对于有序的数组而言,依次确定数组左边的较小得数a/b,c在a/b之后确定。此时可以满足关系:a <= b <= c;故a+b>c&&a+c>b&&b+c>aa+c>bb+c>a是一定成立的,就不用再判断了,减少两次判断,此时就可以通过了。时间复杂度还是O(n^3)。
( 2 ) (2) (2) 解法二:借助有序数组的单调性解题。
还是先对数组nums进行排序,满足关系:a <= b <= c
在这里插入图片描述

( 3 ) (3) (3)

3. 时间复杂度

暴力解法 : O ( n 3 ) O(n^3) O(n3)

对撞双指针: O ( n 2 ) O(n^2) O(n2)

利用单调性,外层循环确定一个数,内层循环确定两个数,减少一层循环。

3. 代码实现

解法一:暴力搜索(也叫遍历)

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        // a+b>c a+c>b b+c>a
        int cnt = 0;
        int n = nums.size();
        sort(nums.begin(), nums.end());
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                for(int k = j + 1; k < n; k++){
                    // if(nums[i] + nums[j] > nums[k]
                    // && nums[i] + nums[k] > nums[j]
                    // && nums[j] + nums[k] > nums[i]){
                    if(nums[i] + nums[j] > nums[k]){
                        cnt++;
                    }
                }
            }
        }
        return cnt;
    }
};

解法二:对撞双指针

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        // 结果计数
        int cnt = 0;
        int n = nums.size();
        // 排序
        sort(nums.begin(), nums.end());
        for(int i = n - 1; i >= 0; i--){
            // 对撞双指针
            int l = 0, r = i - 1;
            while(l < r){
                int sum = nums[l] + nums[r];
                
                if(sum > nums[i]){
                    // a+b>c
                    cnt += r - l;
                    r--;
                }
                else{
                    // a+b<=c
                    l++;
                }
            }
        }
        return cnt;
    }
};

4. 知识与收获

( 1 ) (1) (1) 感受双指针对时间复杂度的降维能力把。


T h e The The E n d End End

相关推荐

  1. 611. 有效三角形个数指针

    2024-03-10 09:50:03       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-10 09:50:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-10 09:50:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-10 09:50:03       82 阅读
  4. Python语言-面向对象

    2024-03-10 09:50:03       91 阅读

热门阅读

  1. 计算机网络 路由算法

    2024-03-10 09:50:03       50 阅读
  2. ChatGpt接口流式输出解决方案

    2024-03-10 09:50:03       44 阅读
  3. 使用Tesseract-OCR对PDF等图片文件进行文字识别

    2024-03-10 09:50:03       49 阅读
  4. 在 build.gradle.kts 添加 阿里云仓库

    2024-03-10 09:50:03       46 阅读
  5. 使用Python合并PDF文件并添加自定义目录及页脚

    2024-03-10 09:50:03       259 阅读
  6. QT绑定信号槽重载

    2024-03-10 09:50:03       49 阅读
  7. 设计模式--装饰器模式(Decorator Pattern)

    2024-03-10 09:50:03       45 阅读
  8. 洛谷P5318 【深基18.例3】查找文献

    2024-03-10 09:50:03       48 阅读