LeetCode 2865 Beautiful Towers I

看到题的前十五分钟,发呆。看似简单,其实不会。暴力可解,但是可能会超时。
题目不搬运了。
既然暴力可解,那顺着暴力的思路,把一些值存下来,是不是就不用重复计算,不超时了。有点像动态规划。
输入数组是maxHeights (原题是list, 这里为了好看假设是数组,真正实现的时候用list实现就行)
使用两个数组来辅助

fa : fa[i]存储第i个值作为塔尖的时候,左侧序列(包括第i个值)的和
fb : fb[i]存储第i个值作为塔尖的时候,右侧序列(包括第i个值)的和

则根据题意,有以下关系
对于fa
f a [ i ] = { m a x H e i g h t s [ 0 ] , i = 0 f a [ i − 1 ] + m a x H e i g h t s [ i ] , i > 0 , m a x H e i g h t s [ i ] ≥ m a x H e i g h t s [ i − 1 ] f a [ j ] + m a x H e i g h t s [ i ] ∗ ( i − j ) , i > 0 , m a x H e i g h t s [ i ] < m a x H e i g h t s [ i − 1 ] fa[i]=\begin{cases} maxHeights[0],\quad i=0 \\\\ fa[i - 1] + maxHeights[i],\quad i\gt0,maxHeights[i]\geq maxHeights[i-1] \\\\ fa[j] + maxHeights[i] * (i - j),\quad i\gt0,maxHeights[i]\lt maxHeights[i-1] \end{cases} fa[i]= maxHeights[0],i=0fa[i1]+maxHeights[i],i>0,maxHeights[i]maxHeights[i1]fa[j]+maxHeights[i](ij),i>0,maxHeights[i]<maxHeights[i1]
其中 j 是从i-10,第一个小于等于maxHeight[i]的值的下标

优化下,可以写成
f a [ i ] = { m a x H e i g h t s [ 0 ] , i = 0 f a [ j ] + m a x H e i g h t s [ i ] ∗ ( i − j ) , i > 0 fa[i]=\begin{cases} maxHeights[0],\quad i=0 \\\\ fa[j] + maxHeights[i] * (i - j),\quad i\gt0 \end{cases} fa[i]= maxHeights[0],i=0fa[j]+maxHeights[i](ij),i>0
同理,fb
f b [ i ] = { m a x H e i g h t s [ i ] , i = l e n − 1 f b [ i + 1 ] + m a x H e i g h t s [ i ] , i < l e n − 1 , m a x H e i g h t s [ i ] ≥ m a x H e i g h t s [ i + 1 ] f b [ j ] + m a x H e i g h t s [ i ] ∗ ( j − i ) , i < l e n − 1 , m a x H e i g h t s [ i ] < m a x H e i g h t s [ i + 1 ] fb[i]=\begin{cases} maxHeights[i],\quad i=len - 1 \\\\ fb[i + 1] + maxHeights[i],\quad i\lt len - 1,maxHeights[i]\geq maxHeights[i+1] \\\\ fb[j] + maxHeights[i] * (j - i),\quad i\lt len - 1,maxHeights[i]\lt maxHeights[i+1] \end{cases} fb[i]= maxHeights[i],i=len1fb[i+1]+maxHeights[i],i<len1,maxHeights[i]maxHeights[i+1]fb[j]+maxHeights[i](ji),i<len1,maxHeights[i]<maxHeights[i+1]
优化下,可以写成
f b [ i ] = { m a x H e i g h t s [ i ] , i = l e n − 1 f b [ j ] + m a x H e i g h t s [ i ] ∗ ( j − i ) , i < l e n − 1 fb[i]=\begin{cases} maxHeights[i],\quad i=len - 1 \\\\ fb[j] + maxHeights[i] * (j - i),\quad i\lt len - 1 \end{cases} fb[i]= maxHeights[i],i=len1fb[j]+maxHeights[i](ji),i<len1
其中 j 是从i+1len-1,第一个小于等于maxHeight[i]的值的下标
len是数组的长度。
则代码如下

public long maximumSumOfHeights(List<Integer> maxHeights) {
        int len = maxHeights.size();
        // 对应fa
        long[] leftsum = new long[len];
        // 对应fb
        long[] rightsum = new long[len];
        leftsum[0] = maxHeights.get(0);
        rightsum[len - 1] = maxHeights.get(len - 1);
        int j;
        for (int i = 1; i < len; ++i) {
               // 算leftsum
                j = i - 1;
                while (j >= 0 && maxHeights.get(j) > maxHeights.get(i)) {
                    --j;
                }
                // 必须加long,否则超出范围
                leftsum[i] = (j >= 0 ? leftsum[j] : 0) + (i - j) * (long)maxHeights.get(i);
               // 算rightsum
                j = len - i;
                while(j < len && maxHeights.get(j) > maxHeights.get(len - 1 - i)) {
                    ++j;
                }
                // 必须加long,否则超出范围
                rightsum[len - 1 - i] = (j < len ? rightsum[j] : 0) + (j - (len - 1 - i)) * (long)maxHeights.get(len - 1 - i);
        }
        long res = 0;
        for (int i = 0; i < len; ++i) {
            res = res > (leftsum[i] - maxHeights.get(i) + rightsum[i]) ? res : (leftsum[i] - maxHeights.get(i) + rightsum[i]);
        }
        return res;
    }

看了下官方的题解,有个单调栈的,有空学下。TODO

你可能感兴趣的:(leetcode,算法)