11. Container With Most Water
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
题意是寻找两块板之间所能容纳的最大水量,用双指针分别从首尾两端遍历,每次移动较短边对应指针,直到较短边变成较长边,并计算此时所能容纳水量,若大于maxarea,则更新maxarea,直到两指针相遇为止。
class Solution {
public:
int maxArea(vector<int>& height) {
int maxarea=0,area=0;
int left=0,right=height.size()-1;
while(left<right){
area=(right-left)*(height[left]>height[right]?height[right]:height[left]);
maxarea=maxarea>area?maxarea:area;
if(height[left]<height[right]){
do{
left++;
}while(left<right && height[left]<height[left-1]);
}else{
do{
right--;
}while(left<right && height[right]<height[right+1]);
}
}
return maxarea;
}
};
15. 3Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
寻找数组中和为0的三个数,注意不能包含重复解。思路是先对数字排序,然后用一层循环遍历一个数字a,用双指针分别指向数组首尾,赋值给b和c,当三个数之和小于0时,low++,当三个数只和大于0时,high--,等于0则加入解集。排序时间复杂度O(nlogn),遍历复杂度O(n^2),总的时间复杂度为O(n^2)。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
int n=nums.size();
for(int i=0;i<n-2;i++){
if(i>0 && nums[i-1]==nums[i]) continue;
int a=nums[i];
int low=i+1;
int high=n-1;
while(low<high){
int b=nums[low];
int c=nums[high];
if(a+b+c==0){
vector<int> v;
v.push_back(a);
v.push_back(b);
v.push_back(c);
result.push_back(v);
while(low<n-1 && nums[low]==nums[low+1]) low++;
while(high>0 && nums[high]==nums[high-1]) high--;
low++;
high--;
}else if(a+b+c>0){
while(high>0 && nums[high]==nums[high-1]) high--;
high--;
}else{
while(low<n && nums[low]==nums[low+1]) low++;
low++;
}
}
}
return result;
}
};
16. 3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).寻找数组内求和最接近目标值的三个数。思路与3Sum类似,加入distance变量用于记录当前与目标值的最小差。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int size=nums.size();
int distance=INT_MAX;
int result=distance;
for(int i=0;i<size-2;i++){
if(i>0 && nums[i-1]==nums[i]) continue;
int low=i+1;
int high=size-1;
while(low<high){
int sum=nums[i]+nums[low]+nums[high];
if(sum==target) return target;
else{
if(abs(sum-target)<distance){
distance=abs(sum-target);
result=sum;
}
if(sum-target<0){
while(low<size && nums[low]==nums[low+1]) low++;
low++;
}else{
while(high>i && nums[high]==nums[high-1]) high--;
high--;
}
}
}
}
return result;
}
};
18. 4Sum
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
寻找数组中和为0的四个数。思路同3Sum,多一层循环遍历。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
if(nums.size()<4) return result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-3;i++){
if(i>0 && nums[i-1]==nums[i]) continue;
vector<int> n(nums.begin()+i+1,nums.end());
vector<vector<int>> ret=threeSum(n,target-nums[i]);
for(int j=0;j<ret.size();j++){
ret[j].insert(ret[j].begin(),nums[i]);
result.push_back(ret[j]);
}
}
return result;
}
vector<vector<int>> threeSum(vector<int> num,int target){
vector<vector<int>> result;
int n=num.size();
for(int i=0;i<n-2;i++){
if(i>0 && num[i-1]==num[i]) continue;
int low=i+1;
int high=n-1;
while(low<high){
int sum=num[i]+num[low]+num[high];
if(sum==target){
vector<int> v;
v.push_back(num[i]);
v.push_back(num[low]);
v.push_back(num[high]);
result.push_back(v);
while(low<n && num[low]==num[low+1]) low++;
while(high>i && num[high]==num[high-1]) high--;
low++;high--;
}else if(sum>target){
while(high>0 && num[high]==num[high-1]) high--;
high--;
}else{
while(low<n && num[low]==num[low+1]) low++;
low++;
}
}
}
return result;
}
};
42. Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
用n个非负整数代表木条高度,计算所有木条所能容纳的最大水量。思路是先找到最高的木条,然后用双指针分别从两端遍历,从左边遍历时,用pre存储从左边起到目前为止最高木条,如果当前木条比pre低,则在result中加入pre与当前木条之差的水量,如果当前木条比pre高,则把pre更新为当前木条高度,直到遍历到最高木条时为止。从右边遍历时也是一样的。
class Solution {
public:
int trap(vector<int>& height) {
int result=0;
int maxHigh=0;
int maxId=0;
for(int i=0;i<height.size();i++){
if(height[i]>maxHigh){
maxHigh=height[i];
maxId=i;
}
}
int pre=0;
for(int i=0;i<maxId;i++){
if(height[i]>pre){
pre=height[i];
}
result+=(pre-height[i]);
}
pre=0;
for(int i=height.size()-1;i>maxId;i--){
if(height[i]>pre){
pre=height[i];
}
result+=(pre-height[i]);
}
return result;
}
};