Container With Most Water

一個非負整數數組a1, a2, …, an 分別代表一系列點 (i, ai),分別過這些點作x軸的垂線,任選兩條線與x軸組成一個容器,求容器最大能盛下多少水。要求複雜度O( n )
注:容器不能傾斜;保證n>=2


最容易想到的就是類似冒泡掃一遍過去,複雜度O( n^2 ),TLE


題解

很容易理解的O( n )方法:雙指針(Two Pointers)

設選擇的兩個點爲(i, a[i])(j, a[j]),則水量C = (j - i)*min(a[i], a[j]); when j>i
數組長度爲n,首先我們令 i = 0; j = n - 1; 此時 (j - i)有最大值;因爲我們要尋找的是水量的最大值,當i或j變化時(i++或j–),(j - i)值必然減小,所以只有min(a[i], a[j])值增大時我們纔有可能使C增大,而使min(a[i], a[j])增大隻有使其中較小的一個變化纔有可能


分情況進行討論:

  • a[i] < a[j] –> i = i+1
    • a[i+1] > a[i] : min(a[i+1], a[j]) >= min(a[i], a[j])
    • a[i+1] < a[i] : min(a[i+1], a[j]) < min(a[i], a[j])
  • a[i] < a[j] –> j = j - 1
    • a[j-1] > a[j] : min(a[i], a[j-1]) == min(a[i], a[j])
    • a[j-1] < a[j] : min(a[i], a[j-1]) <= min(a[i], a[j])

var i=0;
var j=n-1;
while(i<j){
        var t = (j-i)*(a[i]>a[j]?a[j]:a[i]);
        if(t > max){
            max = t;
        }
        if(a[i]>a[j]){
            j--;
        }else{
            i++;
        }
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章