leetcode hard专杀之84. Largest Rectangle in Histogram

来源:互联网 发布:js获取当前日期时间 编辑:程序博客网 时间:2024/05/29 05:03

上篇博客说了,这题是基础,所以这里还是把这题的思路说一下,这题难度蛮高的,动态规划不好做,brute force性能又不够,着实令人头疼,后来还是看了下网上的思路,而且代码实现出来还不是那么符合直觉。


总之思路是这样的,从0~n遍历,对每个i,都以它为中心,分别向左和向右数,任意一个方向一直走,直到左边出现第一个比arr[i]小的index,记为left,同样右边出现第一个比arr[i]小位置记为right,那么从left+1到 right-1这段区域内形成的矩形面积为(right-left-1)*arr[i],即为完整包含arr[i]的情况下能形成的最大矩形,也就是说对每一个i,都存在这么一个唯一的值与之对应,把对应关系记为area[i] = f(i),那么max(area)即为所要求的值。


思路看起来还好理解吧?不过重点不在于好不好理解,而在于为什么会产生这种思路!我觉得主要的一点在于这样是在符合直觉的情况下唯一一种可能比brute force性能更好的方法,而且这里面有在算法上取巧的空间,换句话说,既是你用代码原封不动地实现这种思路(向左一个循环,向右一个循环),可能还是通不过OJ,所以这里取巧方法是,从另外一个角度想,我从0~n遍历,但我不把i定义为中心,而以i为某个中心向右延伸到的首个小于其值的index。转换成这个思路后,就比较好做了,不用写两个循环。不过这里要用个栈做辅助的数据结构,而且这个过程依然不是那么符合直觉,可能需要在纸上画画才能理解。总之,如果面试的时候碰到这种题,那就死翘翘吧。


老实说这段用栈的代码真的不是很符合直觉,可能需要多花时间,反复琢磨才能体会其中精髓。


不废话了,上JB,不对,上Java:


public class Solution {    public int largestRectangleArea(int[] heights){        Stack<Integer> s = new Stack<>();        List<Integer> nre = Arrays.stream(heights).boxed().collect(Collectors.toList());        nre.add(0);        int sum = 0;        int i = 0;        while(i < nre.size()) {            if(s.isEmpty() || nre.get(i) > nre.get(s.peek())) {                s.push(i);                i++;            } else {                int t = s.peek();                s.pop();                sum = Math.max(sum, nre.get(t) * (s.empty() ? i : i - s.peek() - 1));            }        }        return sum;    }}



阅读全文
0 0
原创粉丝点击