直方图面积计算

想要面试高级岗位怕做题是不行的,从这道题开始慢慢刷leetcode

  • 时间限制:1 sec

  • 空间限制:256 MB

  • 问题描述
    有一个直方图,横轴长度为 n,第 i 列的高度为 h[i]。

  • 请你求出在这个直方图中面积最大的子矩阵。

  • 输入格式
    第一行一个正整数 n。

  • 第二行 n 个用空格隔开的非负整数,依次描述 h[1],h[2],…,h[n]。

  • 输出格式
    输出一行一个数,表示最大面积。

import java.io.*;
import java.util.Stack;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(in, out);
        out.close();
    }

    static class Task {

        void solve(InputReader in, PrintWriter out) {
            int a = in.nextInt();
            int[] arrayList=new int[a];
            for (int i=0;i<a;i++){
                arrayList[i]= in.nextInt();
            }
                out.println(MaxRectangleArea(arrayList));
        }
    }

    public static int MaxRectangleArea(int[] height) {
        int area = 0;
        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < height.length; i++) {
            //当前栈顶比扫描到的height[i]小,那么让height[i]进栈
            if (stack.empty() || height[stack.peek()] < height[i]) {
                stack.push(i);
            //如果栈顶比扫描到的height[i]大,那么pop出当前栈顶,并且计算出当前栈顶对应的矩形面积
            //同时用此面积与area比大小,留下最大的作为新的area
            } else {
                int start = stack.pop();
                int width = stack.empty() ? i : i - stack.peek() - 1;
                area = Math.max(area, height[start] * width);
                //回退一格,检查栈顶弹出后下一个元素与height[i]作比较
                //本来i是要+1的,但是由于发生了height[stack.peek()] >= height[i],新的栈顶要重新和height[i]作比较
                //所以这里放置i--
                i--;
            }
        }
        //清空栈,并依次用栈顶元素计算其对应矩形面积
        //栈中元素如果存在,一定是依次递增的,所以矩形的底一定是height.length-stack.peek-1
        while (!stack.empty()) {
            int start = stack.pop();
            int width = stack.empty() ? height.length : height.length
                    - stack.peek() - 1;
            area = Math.max(area, height[start] * width);
        }
        return area;
    }

    static class InputReader {
        BufferedReader reader;
        StringTokenizer tokenizer;

        private InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        private String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        private short nextShort() {
            return Short.parseShort(next());
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private float nextFloat() {
            return Float.parseFloat(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值