给你一个下标从 1 开始的整数数组 numbers
,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target
的两个数。如果设这两个数分别是 numbers[index1]
和 numbers[index2]
,则 1 <= index1 < index2 <= numbers.length
。
以长度为 2 的整数数组 [index1, index2]
的形式返回这两个整数的下标 index1
和 index2
。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例 1:
输入:numbers = [2,7,11,15], target = 9 输出:[1,2]
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
sort(numbers.begin(),numbers.end());
int star = 0,end = numbers.size() - 1;
while(star < end)
{
if(numbers[star] + numbers[end] == target)return {star+1,end+1};
if(numbers[star] + numbers[end] > target)end --;
else star ++;
}
return {};
}
};
根据题意可知,一个numbers 数组一定有两个数加起来等于 target
所以我们先将numbers 进行一个排序。然后设置一个头尾指针。
那么可得 如果 头 + 尾 > 目标值 那么这个数一定在 尾 部的前面 因为 尾部后面的数 + 头 一定大于 目标值; 同理 如果 头 + 尾 < 目标值 那么一定在头的前面;
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> ans;
int n=nums.size();
int star,end;
int i;
for(i = 0; i < n - 2 ;i += 1)
{
if(i && nums[i] == nums[i - 1])continue; //如果数相同就跳过
star = i + 1;
end = n - 1;
if(nums[end - 1] + nums[end] + nums[i] < 0)continue; //最大的三个数加起来都比 0小
if(nums[star] + nums[i+2] + nums[i] > 0)break; //最小的三个数加起来都比 0大
//后面的数相加一定大于0
while(star < end)
{
if(nums[star] + nums[end] + nums[i] == 0)
{
ans.push_back({nums[star],nums[end],nums[i]});
star ++,end --;
while(star < end && nums[star - 1] == nums[star])star++;
while(star < end && nums[end] == nums[end + 1])end --;
}
else
if(nums[star] + nums[end] + nums[i] < 0)
star++;
else
end --;
}
}
return ans;
}
};
可以看作 两数之和 的加强版,将一个固定的数看做目标状态。然后在剩下的数里面寻找
两个数 时的 两数之和 == -目标状态。后面的解法跟 两数之和 就基本没有区别了 ,不过
要注意的是没有重复;
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:
输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
class Solution {
public:
int maxArea(vector<int>& height) {
int star = 0,end = height.size() - 1,min_heig;
int max = 0;
while(star < end)
{
min_heig = std::min(height[star],height[end]);
max = std::max(max,min_heig * (end - star));
if(height[star] < height[end])
star+=1;
else
end -=1;
}
return max;
}
};
同样可以用双指针去做。
证明:
容积 = 短的那段 * 他们的距离
当 star,end 分别指向两端;
如果star 是短的那段,那么当end -= 1 时一定小于当前的值 因为容积 = 短的那段 * 他们的距离。
当end-=1;时 他们的距离 变短。 但是 后来短的那段 一定不会大于 当前 的star。所有可得end是不
可能移动的;