题目:
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;
}
};