文巾解题 11. 盛最多水的容器
1 題目描述
2 解題思路
雙指針
算法流程: 設置雙指針 i,j 分別位于容器壁兩端,根據規則移動指針(規則后文會提及),并且更新面積最大值 res,直到 i >?j 時返回 res。
?
指針移動規則與證明: 每次選定圍成水槽兩板高度 h[i],h[j]中的短板,向中間收窄 1 格。
?
以下證明:
設每一狀態下水槽面積為 S(i, j)(0<=i<j<n),由于水槽的實際高度由兩板中的短板決定,則可得面積公式 S(i, j) = min(h[i], h[j]) × (j - i)。
在每一個狀態下,無論長板或短板收窄 1 格,都會導致水槽 底邊寬度 -1:
若向內移動短板,水槽的短板 min(h[i], h[j])可能變大,因此水槽面積 S(i, j) 可能增大。
若向內移動長板,水槽的短板 min(h[i], h[j])不變或變小,下個水槽的面積一定小于當前水槽面積(j-i)變小了。
因此,向內收窄短板可以獲取面積最大值。
?
從剪枝的角度理解算法:
若不指定移動規則,所有移動出現的 S(i, j) 的狀態數為 C(n, 2),即暴力枚舉出所有狀態。
在狀態 S(i, j)下向內移動短板至 S(i + 1, j)(假設 h[i] < h[j] ),則相當于消去了 {S(i, j - 1), S(i, j - 2), ... , S(i, i + 1)} 狀態集合。而所有消去狀態的面積一定 <= S(i, j):
短板高度:相比 S(i, j) 相同或更短(<= h[i]);
底邊寬度:相比 S(i, j) 更短。
因此所有消去的狀態的面積都 < S(i, j)。
換句話說,我們每次向內移動短板,所有的消去狀態都不會導致丟失面積最大值 。
?
復雜度分析:
時間復雜度 O(N),雙指針遍歷一次底邊寬度 N 。
空間復雜度 O(1),指針使用常數額外空間。
class Solution:def maxArea(self, height: List[int]) -> int:first=0last=len(height)-1 #起始和終止位置的指針max_l=0 #當前最大蓄水量while(first<last):tmp=min(height[first],height[last])*(last-first)max_l=max(tmp,max_l)if(height[first]<=height[last]):first+=1else:last-=1return(max_l)?
總結
以上是生活随笔為你收集整理的文巾解题 11. 盛最多水的容器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 命令集锦
- 下一篇: 文巾解题35. 搜索插入位置