LeetCode复习 栈系列


#20 有效的括号

public boolean isValid(String s) {
        char[] chars = s.toCharArray();
        if (chars.length % 2 != 0) {
            return false;
        }
        Deque<Character> left = new LinkedList<>();
        for (char aChar : chars) {
            if (aChar == '(') {
                left.push(')');
            } else if (aChar == '[') {
                left.push(']');
            } else if (aChar == '{') {
                left.push('}');
            } else if (left.isEmpty() || left.pop() != aChar) {
                return false;
            }
        }
        return left.isEmpty();
    }    


#94 二叉树的中序遍历

public List<Integer> preorderTraversal(TreeNode root) {
        Deque<TreeNode> stack = new LinkedList<>();
        List<Integer> res = new ArrayList<>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {         
                stack.push(root);
                root = root.left;
            } else {
                //出栈相当于递归里的为空返回
                pop = stack.pop();
                res.add(pop.val);
                root = pop.right;
            }
        }
        return res;
    }


#144 二叉树的前序遍历

public List<Integer> preorderTraversal(TreeNode root) {
        Deque<TreeNode> stack = new LinkedList<>();
        List<Integer> res = new ArrayList<>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                res.add(root.val);
                stack.push(root);
                root = root.left;
            } else {
                //出栈相当于递归里的为空返回
                root = stack.pop().right;
            }
        }
        return res;
    }


#145 二叉树的后序遍历

public List<Integer> postorderTraversal(TreeNode root) {
        Deque<TreeNode> stack = new LinkedList<>();
        List<Integer> res = new ArrayList<>();
        TreeNode visited = null;
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                stack.push(root);
                root = root.left;
            } else {
                if (stack.peek().right == null || stack.peek().right == visited) {
                    TreeNode pop = stack.pop();
                    visited = pop;
                    res.add(pop.val);
                } else {
                    root = stack.peek().right;
                }
            }
        }
        return res;
    }


#155 最小栈

class MinStack {
        Deque<Integer> stack;
        Deque<Integer> min;

        public MinStack() {
            stack = new LinkedList<>();
            min = new LinkedList<>();
        }

        public void push(int val) {
            stack.push(val);
            if (min.isEmpty() || val < min.peek()) {
                min.push(val);
            }
        }

        public void pop() {
            if (stack.pop().equals(min.peek())) {
                min.pop();
            }
        }

        public int top() {
            return stack.isEmpty() ? 0 :stack.peek();
        }

        public int getMin() {
            return min.isEmpty() ? 0 : min.peek();
        }
    }


#232 用栈实现队列

class MyQueue {
        Deque<Integer> stack1;
        Deque<Integer> stack2;
        public MyQueue() {
            stack1 = new LinkedList<>();
            stack2 = new LinkedList<>();
        }

        public void push(int x) {
            stack1.push(x);
        }

        public int pop() {
           if (stack2.isEmpty()) {
               pushStack2();
               return stack2.pop();
           }
           return stack2.pop();
        }

        public int peek() {
            if (!stack2.isEmpty()) {
                return stack2.peek();
            }
            pushStack2();
            return stack2.peek();
        }

        private void pushStack2() {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }

        public boolean empty() {
            return stack1.isEmpty() && stack2.isEmpty();
        }
    }


#496 下一个更大元素 I

public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int[] res = new int[nums1.length];
        Deque<Integer> monotoneStack = new LinkedList<>();
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums2.length; i++) {
            while (!monotoneStack.isEmpty() && monotoneStack.peek() < nums2[i]) {
                map.put(monotoneStack.pop(),nums2[i]);
            }
            monotoneStack.push(nums2[i]);
        }
        for (int i = 0; i < nums1.length; i++) {
            res[i] = map.getOrDefault(nums1[i],-1);
        }
        return res;
    }


#114 二叉树展开为链表

public void flatten(TreeNode root) {
        while (root != null) {
            TreeNode left = root.left;
            TreeNode right = root.right;
            TreeNode connect = left;
            if (connect != null) {
                while (connect.right != null) {
                    connect = connect.right;
                }
                connect.right = right;
                root.right = left;
                root.left = null;
            }
            root = root.right;
        }
    }


#173 二叉搜索树迭代器

 static class BSTIterator {
        Deque<TreeNode> stack = new LinkedList<>();
        TreeNode root;
        public BSTIterator(TreeNode root) {
            this.root = root;
        }

        public int next() {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            TreeNode pop = stack.pop();
            if (pop.right != null) {
                root = pop.right;
            }
            return pop.val;
        }

        public boolean hasNext() {
            return root != null || stack.isEmpty();
        }
    }


#394 字符串解码

public String decodeString(String s) {
        Deque<String> multiStack = new LinkedList<>();
        Deque<String> resStack = new LinkedList<>();
        StringBuffer multi = new StringBuffer();
        StringBuffer res = new StringBuffer();
        char[] chars = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            if (chars[i] >= '0' && chars[i] <= '9') {
                multi.append(chars[i] - '0');
            //遇到【先把【前面的数字和字符串存起来
            } else if (chars[i] == '[') {
                multiStack.push(multi.toString());
                resStack.push(res.toString());
                multi = new StringBuffer();
                res = new StringBuffer();
            } else if (Character.isLetter(chars[i])) {
                res.append(chars[i]);
            } else {
                //遇到】开始拼接
                int curMulti = Integer.parseInt(multiStack.pop());
                String s1 = res.toString();
                StringBuffer tempRes = new StringBuffer();
                for (int j = 0; j < curMulti; j++) {
                    tempRes.append(s1);
                }
                res = new StringBuffer(resStack.pop() + tempRes);
            }
        }
        return res.toString();
    }


两数相加

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
       Deque<ListNode> stack1 = new LinkedList<>();
        Deque<ListNode> stack2 = new LinkedList<>();
        while (l1 != null) {
            stack1.push(l1);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.push(l2);
            l2 = l2.next;
        }
        int carry = 0;
        ListNode pre = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            int a = stack1.isEmpty() ? 0 : stack1.pop().val;
            int b = stack2.isEmpty() ? 0 : stack2.pop().val;
            int sum = (a + b + carry)%10;
            carry = (a + b + carry)/10;
            ListNode listNode = new ListNode(sum);
            listNode.next = pre;
            pre = listNode;
        }
        return pre;
    }


#503 下一个更大元素 II

public int[] nextGreaterElement(int[] nums1) {
        int length = nums1.length;
        int[] res = new int[length];
        Arrays.fill(res,-1);
        Deque<Integer> monotoneStack = new LinkedList<>();
        for (int i = 0; i < 2 * length; i++) {
            while (!monotoneStack.isEmpty() && nums1[monotoneStack.peek() % length] < nums1[i % length]) {
                res[monotoneStack.pop() % length] = nums1[i % length];
            }
            monotoneStack.push(i);
        }
        return res;
    }


#739 每日温度

public int[] dailyTemperatures(int[] temperatures) {
        int length = temperatures.length;
        int[] res = new int[length];
        Deque<Integer> monotoneStack = new LinkedList<>();
        for (int i = 0; i < length; i++) {
            while (!monotoneStack.isEmpty() && temperatures[monotoneStack.peek()] < temperatures[i]) {
                res[monotoneStack.peek()] = i - monotoneStack.pop();
            }
            monotoneStack.push(i);
        }
        return res;
    }


#剑指 Offer 36 二叉搜索树与双向链表

public Node treeToDoublyList(Node root) {
        Deque<Node> stack = new LinkedList<>();
        Node first = null;
        Node prev = null;
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                stack.push(root);
                root = root.left;
            } else {
                Node pop = stack.pop();
                if (first == null) {
                    first = pop;
                }
                if (prev != null) {
                    prev.right = pop;
                    pop.left = prev;
                }
                prev = pop;
                root = pop.right;
            }
        }
        first.left = prev;
        prev.right = first;
        return first;
    }


#剑指 Offer 31 栈的压入、弹出序列

 public boolean validateStackSequences(int[] pushed, int[] popped) {
        Deque<Integer> stack = new LinkedList<>();
        int j = 0;
        for (int i = 0; i < pushed.length; i++) {
            stack.push(pushed[i]);
            while (!stack.isEmpty() && stack.peek() == popped[j]) {
                stack.pop();
                j++;
            }
        }
        return stack.isEmpty();
    }


#42 接雨水

public int trap(int[] height) {
        int res = 0;
        Deque<Integer> stack = new LinkedList<>();
        int cur = 0;
        while (cur < height.length) {
            //栈不为空并且当前高度比比栈顶高度高表示有积水开始算能装多少水
            while (!stack.isEmpty() && height[cur] > height[stack.peek()]) {
                //左边的墙
                int h = height[stack.peek()];
                stack.pop();
                if (stack.isEmpty()) {
                    break;
                }
                int distance = cur - stack.peek() - 1;
                int min = Math.min(height[stack.peek()],height[cur]);
                res += distance * (min - h);
            }
            //当前高度比栈顶高度小表示装不了水
            stack.push(cur);
            cur++;
        }
        return res;
    }


#84 柱状图中最大的矩形

 public int largestRectangleArea(int[] heights) {
        int area = 0;
        int[] ints = new int[heights.length + 2];
        System.arraycopy(heights,0,ints,1,heights.length);
        Deque<Integer> stack = new LinkedList<>();
        for (int i = 0; i < ints.length; i++) {
            //对于每个栈顶柱体,左侧比他小的柱体就是栈顶下面的柱体,当前柱体高度比栈顶柱体高度小,即当前柱体是比栈顶柱体高度小的右侧柱体
            //找到左侧和右侧小的柱体就可以计算面积,面积是不包括左侧小的柱体和右侧小的柱体
            // 例如5左侧小的柱体是1 右侧小的柱体是2  2 1 5 6 2 3 5的最大面积是5 6 不包括 1 2
            //当前元素比栈顶元素小就可以算面积
            while (!stack.isEmpty() && ints[i] < ints[stack.peek()]) {
                area = Math.max(area,ints[stack.pop()] * (i - stack.peek() - 1));
            }
            //当前元素比栈顶元素大就入栈因为栈顶到栈底是单调递减的
            stack.push(i);
        }
        return area;
    }


#85 最大矩形

public int largestRectangleArea(int[] heights) {
        int area = 0;
        int[] ints = new int[heights.length + 2];
        System.arraycopy(heights,0,ints,1,heights.length);
        Deque<Integer> stack = new LinkedList<>();
        for (int i = 0; i < ints.length; i++) {
            //对于每个栈顶柱体,左侧比他小的柱体就是栈顶下面的柱体,当前柱体高度比栈顶柱体高度小,即当前柱体是比栈顶柱体高度小的右侧柱体
            //找到左侧和右侧小的柱体就可以计算面积,面积是不包括左侧小的柱体和右侧小的柱体
            // 例如5左侧小的柱体是1 右侧小的柱体是2  2 1 5 6 2 3 5的最大面积是5 6 不包括 1 2
            //当前元素比栈顶元素小就可以算面积
            while (!stack.isEmpty() && ints[i] < ints[stack.peek()]) {
                area = Math.max(area,ints[stack.pop()] * (i - stack.peek() - 1));
            }
            //当前元素比栈顶元素大就入栈因为栈顶到栈底是单调递减的
            stack.push(i);
        }
        return area;
    }

    public int maximalRectangle(char[][] matrix) {
        int[] heights = new int[matrix[0].length];
        int res = 0;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == '1') {
                    heights[j] += 1;
                } else {
                    heights[j] = 0;
                }
            }
            res = Math.max(res,largestRectangleArea(heights));
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值