11. Container With Most Water [medium]
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 and n is at least 2.
The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
Example:
Input: [1,8,6,2,5,4,8,3,7] Output: 49
- 思路1:O(n^2)的方法很蠢。然后就超时了。
class Solution {
public:
int maxArea(vector<int>& height) {
int Max = INT_MIN;
for(int i = 0; i < height.size(); i++) {
for(int j = i + 1; j < height.size(); j++) {
Max = max(Max, (j - i) * min(height[i], height[j]) );
}
}
return Max;
}
};
- 思路2 : 肯定是区间越长,柱子越高围出来的面积越大。所以还是two pointers。从两侧算面积,要让面积变大,那只能柱子越来越高,所以就看哪边柱子矮,矮的那一边尝试再往前走一步。
class Solution {
public:
int maxArea(vector<int>& height) {
int l = 0, r = height.size() - 1;
int Max = INT_MIN;
while(l < r) {
Max = max(Max, (r - l) * min(height[l], height[r]) );
if(height[l] < height[r]) {
l++;
} else {
r--;
}
}
return Max;
}
};
15. 3Sum [medium]
Given an array nums
of n integers, are there elements a, b, c in nums
such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
- 思路:先排序,再转化为two sum问题。
- 注意:
- 解决重复元素
- 1. 我用了一个set来保存,重载了operator()总体速度比较慢。
- 2. 然后我尝试不用set,速度快了一点。
- 如果有 4sum 就不太好解决了~
- 解决重复元素
实现一:
class MyHash{
public:
size_t operator()(const vector<int> nums) const {
size_t ret = 0;
for(int a : nums) {
ret ^= hash<int>()(a);
}
return ret;
}
};
class Solution {
public:
vector<vector<int>> twoSum(vector<int>& nums, int begin, int target) {
int l = begin, r = nums.size() - 1;
vector<vector<int>> ret;
while(l < r) {
if(nums[l] + nums[r] == target) {
ret.push_back({nums[l++], nums[r--]});
} else if(nums[l] + nums[r] > target) {
r--;
} else {
l++;
}
}
return ret;
}
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ret;
sort(nums.begin(), nums.end());
unordered_set<vector<int>, MyHash> checkMap;
for(int i = 0; i < nums.size(); i++) {
if(i != 0 && nums[i] == nums[i - 1]) {
continue;
}
vector<vector<int>> tmp = twoSum(nums, i + 1, 0 - nums[i]);
if(tmp.size() > 0) {
for(vector<int> &vec : tmp) {
vec.insert(vec.begin(), nums[i]);
if (checkMap.find(vec) == checkMap.end()) {
ret.push_back(vec);
checkMap.insert(vec);
}
}
}
}
return ret;
}
};
实现二:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> ret;
int len = nums.size();
for(int i = 0; i < len; i++) {
if (i != 0 && nums[i - 1] == nums[i])
continue;
int target = 0 - nums[i];
for(int l = i + 1, r = len - 1; l < r;) {
int sum = nums[l] + nums[r];
if(sum == target) {
ret.push_back({nums[i], nums[l++], nums[r--]});
while(l < r && nums[l - 1] == nums[l]) l++;
while(l < r && nums[r + 1] == nums[r]) r--;
} else if(sum < target){
l++;
} else {
r--;
}
}
}
return ret;
}
};
16. 3Sum Closest [medium]
Given an array nums
of n integers and an integer target
, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example:
Given array nums = [-1, 2, 1, -4], and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
- 思路:最接近也就是0。所以判断的时候,不是判断和target是不是一样。而是判断和target距离大小。还是计算三个数的和,目的是要向target靠近,所以如果大了r--。如果小了l++。然后更新一下距离dis就好。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int len = nums.size(), dis = INT_MAX, ret = nums[1] + nums[0] + nums[2];
sort(nums.begin(), nums.end());
for(int i = 0; i < len; i++) {
for(int l = i + 1, r = len - 1; l < r; ) {
int sum = nums[i] + nums[l] + nums[r];
if(sum == target) return sum;
else if(sum < target) l++;
else r--;
int newDis = abs(sum - target);
if(newDis < dis) {
dis = newDis;
ret = sum;
}
}
}
return ret;
}
};