再写写

Title

众所周知


package leetcode.editor.cn;

//给出一个字符串 s(仅含有小写英文字母和括号)。 
//
// 请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。 
//
// 注意,您的结果中 不应 包含任何括号。 
//
// 
//
// 示例 1: 
//
// 输入:s = "(abcd)"
//输出:"dcba"
// 
//
// 示例 2: 
//
// 输入:s = "(u(love)i)"
//输出:"iloveu"
// 
//
// 示例 3: 
//
// 输入:s = "(ed(et(oc))el)"
//输出:"leetcode"
// 
//
// 示例 4: 
//
// 输入:s = "a(bcdefghijkl(mno)p)q"
//输出:"apmnolkjihgfedcbq"
// 
//
// 
//
// 提示: 
//
// 
// 0 <= s.length <= 2000 
// s 中只有小写英文字母和括号 
// 我们确保所有括号都是成对出现的 
// 
// Related Topics 栈 
// 👍 145 👎 0

import java.util.ArrayDeque;
import java.util.Deque;

public class 反转每对括号间的子串 {
    public static void main(String[] args) {
        Solution solution = new 反转每对括号间的子串().new Solution();
        System.out.println(solution.reverseParentheses("(ed(et(oc))el)"));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        Node root = new Node(),tmp;
        int len = 0, cur = -1;
        String str;

        public String reverseParentheses(String s) {
            len = s.length();
            str = s;
            dfs(root);
            return reslove(root);
        }

        public void dfs(Node foo) {
            cur++;
            if (cur == len || str.charAt(cur) == ')')
                return;
            if (str.charAt(cur) == '(') { // 如果是( 则和下一个 ) 之间的内容构成 引用节点
                tmp = new Node();
                tmp.isOrder = !foo.isOrder;  // 每经过一个 ( 就要改变子节点的存储顺序
                foo.put(tmp);
                dfs(tmp);
            } else {
                foo.put(new Node(str.charAt(cur)));
            }
            dfs(foo);
        }

        StringBuilder sb = new StringBuilder();

        public String reslove(Node node) {
            while (!node.deque.isEmpty()) {
                tmp = node.deque.pop();
                if (tmp.isRef()) {
                    reslove(tmp);
                } else {
                    sb.append(tmp.ch);
                }
            }
            return sb.toString();
        }
    }


    /**
     Node 有两种用法
     1. 存储值
     2. 作为引用节点,不存储值,其deque为子节点
     */
    class Node {
        public Deque<Node> deque;
        public boolean isOrder = true;
        public char ch='\\'; //特殊标记用来判断是不是 Ref 引用节点

        /**
         提供了两个构造器,无参构造器才会初始化队列,降低内存占用,似乎没降低多少
         */
        public Node(char ch) {
            this.ch = ch;
        }

        public Node() {
            deque = new ArrayDeque<>();
        }
        public boolean isRef(){
            return ch=='\\';
        }

        // 统一 的 put 方法,直接调用不用管是正着放还是反着放。
// 每经过一个 ( 就要改变子节点的存储顺序
        public void put(Node node) {
            if (isOrder) {
                deque.addLast(node);
            } else {
                deque.addFirst(node);
            }
        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}

123

posted @ 2021-05-26 21:41  Taofoo  阅读(53)  评论(0)    收藏  举报