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.
面試中比較常問的一道題,開始還以為是選擇兩個極大值點和一個極小值點,理解錯了
第一種解法,直接暴力,時間複雜度O(n^2)
第二種解法,有點類似一次快排的過程
#include <iostream> #include <vector> #include <algorithm> using namespace std; int maxArea(vector<int> &height){ int maxWaterArea = 0; int left = 0, right = height.size()-1; while (left < right) { maxWaterArea = max((right-left)*min(height[left],height[right]),maxWaterArea); if (height[left] < height[right]) left++; else right--; } return maxWaterArea; }
關於如何證明最大值會出現在上述移動的方法中?可以用反證法證明。
當前首尾指標分別是i和j,其中A[i] < A[j],那麼移動i。
假設有個k,在i和j之間,A[k]和A[i]組成容器所容納的水最多,那麼勢必A[k]>A[j]
然而,A[i]和A[k]組成的容器的容量(k-i)*min(A[i],A[k]),即(k-i)*A[i],小於A[i]與A[j]所組成的容器大小:(j-i)*A[i]。
所有要移動i,而不是移動j