Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 2866. Beautiful Towers II

Woodyiiiiiii opened this issue · comments

2866. Beautiful Towers II

2866. Beautiful Towers II

讲解:
前后缀分解+单调栈(附题单!)Python/Java/C++/Go

类似题目:
看题解总结,最经典的是接雨水问题。
1081. Smallest Subsequence of Distinct Characters
456. 132 Pattern

单调栈 + 前后缀分解

这道题我的思路是类似rerooting的做法,但无法找到移动之间点的关联,所以只能比赛中坐牢了。

这道题的关键是利用好山峰数组的特性,找到移动的关键——单调性。从而想到维护单调栈,计算距离。

我的单调栈的知识点太薄弱了,一点都想不到利用单调栈。所以还是要多练习单调栈。题目要求有序的话可以从单调栈考虑

class Solution {
    public long maximumSumOfHeights(List<Integer> maxHeights) {
        int n = maxHeights.size();
        LinkedList<Integer> st = new LinkedList<>();
        st.add(n);
        long sum = 0;
        long[] suf = new long[n];
        for (int i = n - 1; i >= 0; i--) {
            int h = maxHeights.get(i);
            while (st.size() > 1 && maxHeights.get(st.peek()) >= h) {
                int p = st.pop();
                sum -= ((long) maxHeights.get(p) * (st.peek() - p));
            }
            int peek = st.peek();
            st.push(i);
            sum += (long) (peek - i) * h;
            suf[i] = sum;
        }
        st.clear();
        st.add(-1);
        sum = 0;
        long ans = 0;
        for (int i = 0; i < n; i++) {
            int h = maxHeights.get(i);
            while (st.size() > 1 && maxHeights.get(st.peek()) >= h) {
                int p = st.pop();
                sum -= ((long) maxHeights.get(p) * (p - st.peek()));
            }
            int peek = st.peek();
            st.push(i);
            sum += (long) (i - peek) * h;
            ans = Math.max(ans, sum + (i + 1 < n ? suf[i + 1] : 0));
        }
        return ans;
    }
}

时间复杂度:O(n),空间复杂度:O(n)。