首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【优选算法必刷100题】第005~006题(双指针算法):有效三角形的个数和查找总价值为目标值的两个商品

【优选算法必刷100题】第005~006题(双指针算法):有效三角形的个数和查找总价值为目标值的两个商品

作者头像
用户11915063
发布2025-11-20 09:55:34
发布2025-11-20 09:55:34
880
举报

005.有效三角形的个数

题目链接:

611. 有效三角形的个数 - 力扣(LeetCode)

题目描述:

题目示例:

解法:(排序+双指针)

暴力枚举的方法还是不在这里展示了,大家可以自己写写,但是肯定是过不了的

算法思路:

先将数组排序。

判断三角形的优化方法:

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

根据【上述优化思想】我们可以固定一个【最长边】,然后在比这条边小的有序数组中找出一个二元组,使得这个二元组之和大于这个最长边。由于数组是有序的,我们可以利用【双指针】来优化

设最长边枚举到 i 位置 ,区间 【left,right】 是 i 位置左边的区间(也就是比它小的区间):

1.如果 nums[left] + nums[right] > nums[i];

  • 说明【left,right-1】区间上的所有元素均可以与 nums[right] 构成比 nums[i] 大的二元组
  • 满足条件的有 right - left
  • 此时 right 位置的元素的所有情况相当于全部考虑完毕,right--,进入下一轮判断

2.如果 nums[left] + nums[right] <= nums[i]

  • 说明 left 位置的元素是不可能与 【left+1,right】位置上的元素构成满足条件的二元组
  • left 位置的元素可以舍去, left++ 进去下轮循环
C++代码演示:
代码语言:javascript
复制
class Solution {
public:
    int triangleNumber(vector<int>& nums) 
    {
        //优化
        sort(nums.begin(),nums.end());
        //利用双指针
        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;
    }
};
算法总结&&笔记展示:

博主笔记(字迹有点丑,请大家见谅):


006.查找总价值为目标值的两个商品

题目链接:

LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

题目描述:

题目示例:

解法:(双指针-对撞指针)

暴力枚举还是会超时,这里就不展示了。

算法思路:

注意到本题是升序的数组,因此可以用【对撞指针】优化时间复杂度。

算法流程:(附带算法分析,为什么可以使用对撞指针):

1.初始化 left,right 分别指向数组的左右两端(这里不是我们理解的指针,而是数组的下标)

2.当 left < right 的时候,一直循环

2.1当 nums[left] + nums[right] == target 时,说明找到结果,记录结果,并且返回;

2.2当 nums[left] + nums[right] < target 时:

  • 对于 nums[left] 而言,此时 nums[right] 相当于是 nums[left] 能碰到的最大值(这里是升序数组)。如果此时不符合要求,说明在这个数组里面,没有别的数符合 nums[left] 的要求了因此,我们可以大胆舍去这个数。让 left++,去比较下一组数据;
  • 那对于 nums[right] 而言,由于此时两数之和是小于目标值的, nums[right] 还可以选择比 nums[left] 大的值继续努力达到目标值,因此 right 指针我们按兵不动

3.当 nums[left] + nums[right] > target 时。同理我们可以舍去 nums[right],让 right-- ,继续比较下一组数据,而 left 指针不变

C++代码演示:
代码语言:javascript
复制
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target)
    {
        int left=0,right=price.size()-1;
        while(left<=right)
        {
            int sum=price[left]+price[right];
            if(sum>target) right--;
            else if(sum<target) left++;
            else return {price[left],price[right]};
        }    
        //照顾编译器
        return {-1,-1};
    }
};
算法总结&&笔记展示:

博主笔记(字迹有点丑,请大家见谅):


往期回顾:

【优选算法必刷100题】第001~002题(双指针算法):移动零、复写零问题

【优选算法必刷100题】第003~004题(双指针算法):快乐数和盛水最多的容器

总结:本篇博客介绍了两个基于双指针算法的高效解题方法。强调排序预处理和指针移动策略在优化算法中的关键作用。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-10-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 005.有效三角形的个数
    • 解法:(排序+双指针)
      • 算法思路:
    • C++代码演示:
    • 算法总结&&笔记展示:
  • 006.查找总价值为目标值的两个商品
    • 解法:(双指针-对撞指针)
      • 算法思路:
    • C++代码演示:
    • 算法总结&&笔记展示:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档