当前位置: 首页 > article >正文

【C++算法】6.双指针_有效三角形的个数

文章目录

    • 题目链接:
    • 题目描述:
    • 解法
    • C++ 算法代码:
    • 图解:


题目链接:

611.有效三角形的个数


题目描述:

8fae7351848e834f705d9f3eb07c33a0


解法

数学知识:

给我们3个数,判断是否能够构成三角形。

平时:a+b>c,a+c>b,b+c>a(判断三次)

如果已知3个数的大小 ,我们可以只判断较小的两个数之和是否大于第三个数。(判断一次)

我们可以先对整个数组排序。

解法一(暴力求解)

三层 for 循环枚举出所有的三元组,并且判断是否能构成三角形。

如果能构成三角形,需要满足任意两边之和要大于第三边。但是实际上只需让较小的两条边之和大于第三边即可。

经过我们的优化后,暴力枚举法的时间复杂度从3n3变成了nlogn+n3

解法二(排序 + 双指针)

排完序后,数组就有序了。我们就可以利用单调性使用双指针算法来解决问题。

6cae50b50e6bd8520765e4f472789f80

比如如果a,b,c取如图的位置。a+b>c,那么left往后移动,得到的结果都可以组成三角形。

177655d6549d09137ea77aebc914b10a

如果a,b,c取如图的位置。a+b<=c,那么无论left往后移动多少,得到的结果都不可以组成三角形。

87ad3b76f1556ab6b0ddeec6d4779c5c

步骤:

  1. 先固定最大的数(固定n次)
  2. 在最大的数的左区间内,使用双指针算法 ,快速统计出符合要求的三元组的个数。
  3. 然后更换固定的最大的数 ,依次类推。

C++ 算法代码:

解法一(暴力求解)(会超时)O(nlogn+n3)

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        // 1. 排序
        sort(nums.begin(), nums.end());
        int n = nums.size(), ret = 0;
        // 2. 从小到大枚举所有的三元组
        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])
                        ret++;
                } 
            }
        }
        return ret;
    }
};

解法二(排序 + 双指针)O(n2)

class Solution 
{
public:
    int triangleNumber(vector<int>& nums) 
    {
        // 1. 优化,排序一下数组
        sort(nums.begin(), nums.end());
        // 2. 利用双指针解决问题
        int ret = 0, 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;
    }
};

图解:

nums=[2,2,3,4]

  1. 优化,排序一下数组,原数组已经顺序了,所以没有变化。

  2. 进入第一层循环,i=3,left=0,right=2

    nums[0] + nums[2] > nums[3]

    ret=ret + right - left=2

    right--,right=1

  3. i=3,left=0,right=1

    nums[0] + nums[1] = nums[3]

    left++,left=1

    跳出while循环,i--

  4. i=2,left=0,right=1

    nums[0] + nums[1] > nums[2]

    ret=ret + right - left=3

    right--,right=0

    跳出while循环,i--

  5. i=1跳出外层for循环

  6. ret=3


http://www.kler.cn/news/325641.html

相关文章:

  • Android 10.0 系统framework层修改第三方app的dpi的属性功能实现
  • mmseqs2蛋白质聚类数据格式转化
  • C++进阶知识1继承
  • 从零预训练一个tiny-llama#Datawhale组队学习Task2
  • [题解] Codeforces Round 976 (Div. 2) A ~ E
  • OpenCV-图像拼接
  • C++游戏开发:构建高性能、沉浸式游戏体验的关键
  • 无人机之集群路径规划篇
  • 「系列投研|01」建立自己的移动比特币银行——赛道概况
  • Python办公自动化案例:实现XMind文件转换成Excel文件
  • AIGC: 从两个维度快速选择大模型开发技术路线
  • el-table初始化时根据传入数据选中某些行
  • HTML中的盒子模型(内置练习及答案)
  • 医院排班|医护人员排班系统|基于springboot医护人员排班系统设计与实现(源码+数据库+文档)
  • git 查看已经commit但是还没有push的所有文件变动内容
  • upsample nearest 临近上采样实现方式
  • Python: RAII:函数执行完毕,socket对象主动发送fin
  • golang Get: context deadline exceeded (Client.Timeout exceeded while aw
  • 第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)征稿
  • Python 学习之生成图形验证码
  • 谷神后端$vs.proc.invoke.stock.loadMap
  • golang语法基础
  • 【大数据应用开发】2023年全国职业院校技能大赛赛题第01套
  • 基于php的助农生鲜销售系统
  • vmware 操作系统安装
  • 常见框架漏洞复现
  • IT运维挑战与对策:构建高效一体化运维管理体系
  • Chapter 2 - 1. Understanding Congestion in Fibre Channel Fabrics
  • Redis: RDB与AOF的选择和容灾备份以及Redis数据持久化的优化方案
  • X86架构(九)——保护模式的进入