米哈游最新面试题 有效三角形的个数

题目:
611. 有效三角形的个数
给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。

示例 1:

输入: [2,2,3,4]
输出: 3
解释:
有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3
注意:

数组长度不超过1000。
数组里整数的范围为 [0, 1000]。

思路:
我们的思路是先将数组排序,
我们判断条件是 当a<b<c 时 当a+b>c a,b,c三条边肯定可以组成三角形

因此我们每次循环时保证 j=nums.size()-1-----0 也就是固定最大值

left=0;
right=j-1;
然后找到满足他条件的 第一个出现的 nums[left]+nums[right]>nums[j]
我们求 left到right 找出两个数 看有多少组成公式 组合问题 (代码中没有其实用的是组合的思想,注意可以包含重复数字)

当nums[left]+nums[right]<=nums[j] left++;

代码:

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

         /**
    *   双指针
    *   1 排序,固定最长边
    *   2 若left满足两边之和大于第三边,固定i,right,left右移增大三角形较小的两边和,则left到right - 1共right - left个满足三角形条件
    *   3 将right左移,两边和减小,判断三角形大于第三边的最小值
    *   4 若两边和不满足三角形条件,则左移,增大三角形较小的两边和
    **/
    
    sort(nums.begin(), nums.end());
    int len = nums.size();
    int res = 0;

    for(int i = len - 1; i >= 0; i --){
        int left = 0, right = i - 1;
        while(left < right){
            if(nums[left] + nums[right] > nums[i]){
            	//代表 [left,【left+1,left+2,left+3,left+4...right】,i]符合条件
                res += right - left;
                 right--;
            }else{
                left++;
            }
        }
    }

    return res;







    }
};

题目:
15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
通过次数367,604

思路:

代码:

class Solution {
private:
    vector<vector<int>> result_vv;

public:
    vector<vector<int>> threeSum(vector<int>& nums)
    {
        if(nums.size()<=2)//判断nums中是否有三个数
        {
            return result_vv;
        } 
        sort(nums.begin(),nums.end());//先排序
        if (nums[0] > 0 || nums[nums.size() - 1] < 0)
         {
            return result_vv;
        }
        for(int i=0;i<=nums.size()-3;i++)//nums.size()-1是倒数第一个数
        {
             if (nums[i] > 0) {
                    return result_vv;
            }
           if(i>0&&nums[i]==nums[i-1])//当前元素与之间元素相同
           {
               continue;
           }

            int left=i+1;
            int right=nums.size()-1;
           while(left<right)
           {
               int sum=nums[i]+nums[left]+nums[right];
               if(sum==0)
               {
                   vector<int> temp_v;
                   temp_v.push_back(nums[i]);
                   temp_v.push_back(nums[left]);
                   temp_v.push_back(nums[right]);

                   result_vv.push_back(temp_v);

                   while(left<right&&nums[left]==nums[left+1])
                   {
                       left++;
                   }
                   left++;

                    while(left<right&&nums[right]==nums[right-1])
                    {
                        right--;
                    }
                    right--;

               }else if(sum<0)
               {
                   
                   left++;
  
               }else if(sum>0)
               {
                   right--;
               }
               

           }

        }
        return result_vv;
    }
};
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值