1. 程式人生 > 實用技巧 >IOS:利用UIImageView製作幀動畫

IOS:利用UIImageView製作幀動畫

技術標籤:Leetcode

84. 柱狀圖中最大的矩形

思路:

方法一:

如果暴力解法,對於某一個柱子,我們讓它往兩邊找,直到找到坑為止就算到頭了,然後算面積就是了

但是這樣也發現,如果我們從頭往後遍歷,要是下降了,那後面的肯定是前面那個的右邊界,對應的他的左邊界可以自己往前去搜索一下
可以用while()一直找到比它小的heights,然後就是它的左邊界
但是這樣的話,很容易出現重複的遍歷

方法二

對於某個柱子
如果它後面是 嚴格下降的話,那它的右邊界就是他本身,到頭了
如果後面是 上升的話,那麼它的右邊界是不能確定的,需要往後找了,每一個都可能是它的右邊界,
所以每一個都要和當前沒確定右邊界的柱子比較一下,如果自己比沒確定邊界的小,那這個位置的就找到自己屬於的右邊界了

但是如果比較的話,我們應該和最大的比,比完了如果比它小,那它的右邊界就確定了,然後再看次小的,看看能不能確定它的右邊界看樣子才合理

因此我們需要一個能儲存未確定右邊界的資料結構,並且還能按照順序排列,而且我們用的時候拿出來是最大值,很容易想到,就是棧
當然我們應用的過程也肯定是有序的,因為我們每次拿數的時候先看看自己是不是比沒確定右邊界的最大的值 嚴格小,
如果小的話,我就把它拿出來了,因為它的右邊界已經確定了
如果大的話,我自己就塞進去了,因為我確定不了了

這樣一想,好像可以再優化
我們把第一次和後面的比較的直接也算進這個迴圈呢,不就是把自己壓入棧麼?

還有一點我沒有發現,他的左邊界怎麼確定,我一開始以為可以通過反向的方法來確定它的左邊界

但是看到一個題解我突然醒悟,棧裡面既然是單調增的,那麼對應的這個柱子左邊的不就是它的左邊界麼?
因為中間的被彈出去的實際上是被我和前面那個小矮子一起把它給擠出去了

class Solution {
public:
   /*
思路:
    如果暴力解法,對於某一個柱子,我們讓它往兩邊找,直到找到坑為止就算到頭了,然後算面積就是了

    但是這樣也發現,如果我們從頭往後遍歷,要是下降了,那後面的肯定是前面那個的右邊界,對應的他的左邊界可以自己往前去搜索一下
    可以用while()一直找到比它小的heights,然後就是它的左邊界
    但是這樣的話,很容易出現重複的遍歷


*/
//從左到右遍歷,記錄每個柱子的左邊界
/* 對於某個柱子 如果它後面是 嚴格下降的話,那它的右邊界就是他本身,到頭了 如果後面是 上升的話,那麼它的右邊界是不能確定的,需要往後找了,每一個都可能是它的右邊界, 所以每一個都要和當前沒確定右邊界的柱子比較一下,如果自己比沒確定邊界的小,那這個位置的就找到自己屬於的右邊界了 但是如果比較的話,我們應該和最大的比,比完了如果比它小,那它的右邊界就確定了,然後再看次小的,看看能不能確定它的右邊界看樣子才合理 因此我們需要一個能儲存未確定右邊界的資料結構,並且還能按照順序排列,而且我們用的時候拿出來是最大值,很容易想到,就是棧 當然我們應用的過程也肯定是有序的,因為我們每次拿數的時候先看看自己是不是比沒確定右邊界的最大的值 嚴格小, 如果小的話,我就把它拿出來了,因為它的右邊界已經確定了 如果大的話,我自己就塞進去了,因為我確定不了了 這樣一想,好像可以再優化 我們把第一次和後面的比較的直接也算進這個迴圈呢,不就是把自己壓入棧麼? 還有一點我沒有發現,他的左邊界怎麼確定,我一開始以為可以通過反向的方法來確定它的左邊界 但是看到一個題解我突然醒悟,棧裡面既然是單調增的,那麼對應的這個柱子左邊的不就是它的左邊界麼? 因為中間的被彈出去的實際上是被我和前面那個小矮子一起把它給擠出去了 */ int largestRectangleArea(vector<int>& heights) { stack<int> st; st.push(-1); int maxArea = 0; int n = heights.size(); for (int i = 0; i < heights.size(); i++) { while (st.top() != -1 && heights[st.top()] > heights[i]) { //可以夾出去當前的了,棧頂的最大面積已經確定了 int cur = st.top();//可以確定的號 st.pop(); int left = st.top() + 1; int right = i;//左閉又開 maxArea = max(maxArea, (right - left) * heights[cur]); } st.push(i); } while (st.top() != -1) { int cur = st.top();//可以確定的號 st.pop(); int left = st.top() + 1; int right = n;//一直到最後都沒人消掉它,說明它可以延續到最後 maxArea = max(maxArea, (right - left) * heights[cur]); } return maxArea; } };