1. 程式人生 > 其它 >演算法之雙指標(共同點:核心邏輯思路:即先找到比較小的區域(例如決定了存水量),然後在比較小的區域中找到一個最大值))~盛最多水的容器~~~接雨水

演算法之雙指標(共同點:核心邏輯思路:即先找到比較小的區域(例如決定了存水量),然後在比較小的區域中找到一個最大值))~盛最多水的容器~~~接雨水

演算法之雙指標(共同點:核心邏輯思路:即先找到比較小的區域(例如決定了存水量),然後在比較小的區域中找到一個最大值

~盛最多水的容器~~~接雨水

1,盛最多水的容器

題意:

給你 n 個非負整數 a1,a2,...,an,每個數代表座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0) 。找出其中的兩條線,

使得它們與 x 軸共同構成的容器可以容納最多的水。
說明:你不能傾斜容器。

解法:雙指標

思路:面積的公式~寬(下標之差~雙指標)* 高(取決於左右兩側兩個柱子中比較小的那個柱子)

詳細:咱從左側(left = 0),右側(right = height.size() - 1)循壞:

如果高出現在左側: if (height[left] <= height[right]) 左側的柱子比右側低,則 高 的可能性出現在左側區域,需要在左側找到一個最大的值(作為高)

同時,通過更新 當前的面積(如果當前的 寬(雙指標下標之差)* 高(左側某個最大值)與前一個面積比較,大於則更新面積

右側同理。。。。

總結:“左側的柱子比右側低,則 高 的可能性出現在左側區域,需要在左側找到一個最大的值(作為高)”~思路,即先找到比較小的區域,然後在比較小的區域中找到一個最大值
  public int maxArea(int[] height) {
            int
left = 0, right = height.length - 1; int ans = 0; while (left < right) { //面積公式 高:最小的 【左柱子,右柱子】 int area = Math.min(height[left], height[right]) * (right - left); ans = Math.max(ans, area); // 需要找小的: if (height[left] <=
height[right]) { // 左側柱子比較低,較小的柱子可能性出現在左側 ++left; //遍歷找那個最大值,同時更新面積,最後得到的面積即最大面積啦 } else { --right; } } return ans; }

2,接雨水

題意:

給定n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。

解法:雙指標

思路: 當前水柱A上可以接收的水量取決於左右兩側最低那個柱子與它的高度差

(例如左側比右側低,則左側區域決定了它的高度差)然後再左側區域中找到最高的柱子~(與當前水柱A)最大高度差,即單位水量

詳細:咱從左側(left = 0),右側(right = height.size() - 1)循壞:

如果比較低的柱子出現在左側:if (height[left] <= height[right]) 則決定水柱A最大接收水量的可能性出現在左側區域,

需要在左側找到一個最大的值

同時,通過更新 當前的左側最大水柱(當前height[left] 與前一個 left_max 比較,大於則更新左側最大水柱

右側同理。。。。

public int trap(int[] height) {
        int left = 0, right = height.length - 1;
        int ans = 0;
        int left_max = 0, right_max = 0;
        while (left < right) {
            if (height[left] < height[right]) { // 左側柱子比較低,較小的柱子(決定存水量)可能性出現在左側
                if (height[left] >= left_max) {
                    left_max = height[left];
                } else {
                    ans += (left_max - height[left]);  //計算當前儲存的水量
                }
                ++left;  //遍歷找那個最大值,同時更新最大值,最後得到的即是最大值啦
            } else {
                if (height[right] >= right_max) {
                    right_max = height[right];
                } else {
                    ans += (right_max - height[right]);
                }
                --right;
            }
        }
        return ans;
    }