寫在前面:
程序員分兩種,會算法的程序員和不會算法的程序員。幾乎沒有一個一線互聯網公司招聘任何類別的技術人員是不考算法的,程序猿們都懂的,現在最權威流行的刷題平臺就是 LeetCode。
Question:
Difficulty:Medium Tag:Array
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.
Solution:
以下代碼皆是本人用 C++寫的,覺得還不錯的話別忘了點個贊哦。各位同學們如果有其他更高效解題思路還請不吝賜教,多多學習。
A1、暴力解法
粗暴進行循環遍歷,問題復雜化,不可取
Time complexity : O(n^2)Time Limit Exceeded
,代碼如下
class Solution {
public:
int maxArea(vector<int>& height) {
int maxArea = 0;
for (int i=0; i<height.size()-1; i++) {
for (int j=i+1; j<height.size(); j++) {
int area = std::min(height[i], height[j])*(j-i);
maxArea = std::max(maxArea, area);
}
}
return maxArea;
}
};
A2、雙指針解法
- 原則上需要遍歷所有組成情況進行比較,如上雙重循環遍歷
- 若想減少遍歷次數,必需排除一些情況的比較
-
left
、right
為數組左右邊緣元素位置,此時h
最大,兩頭指針向中間靠攏時h
逐漸縮小 - 所以只有在
left
或right
高度增大時面積才有可能怎能增大(其他高度小的情況可排除不必比較)
也就是以
height[0]
,height[n-1]
的面積為基準,把所有情況分為大于此面積和小于此面積2種情況,然后把一定小于此面積的情況排除掉不用比較,只比較可能大于此面積的情況,提高了效率。
算法時間復雜度 O(n),Runtime: 9 ms
,代碼如下
int x=[](){
std::ios::sync_with_stdio(false); //關閉STDIN和CIN同步 減少CIN讀入的時間,可以減少50%以上。
cin.tie(NULL);
return 0;
}();
class Solution {
public:
int maxArea(vector<int>& height) {
int maxArea = 0;
int left = 0;
int right = (int)height.size() - 1;
while (left < right) {
int h = min(height[left], height[right]);
maxArea = max(maxArea, (right - left) * h);
while (height[left] <= h && left < right) left++;
while (height[right] <= h && left < right) right--;
}
return maxArea;
}
};