题解 | #二叉搜索树的后序遍历序列【TODO】#

二叉搜索树的后序遍历序列

http://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd

描述

思路1:分治

  1. 后序遍历最后一个元素一定是是根节点,先遍历完左子树,再遍历右子树。
  2. 找到第一个比根节点大的数,即左子树和右子树的分界点。
  3. 将序列分为三段[4,8,6,12,16,14,10],根节点为10,左子树为[4,8,6],右子树为[12,16,14]
  4. 左子树都小于根节点,右子树都大于根节点。否则不是二叉搜索树
  5. 分治:对左右子树分别递归判断
public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length == 0) {
            return false;
        }
        return recur(sequence, 0, sequence.length - 1);
    }
    boolean recur(int[] sequence, int left, int right) {
        if(left >= right) {
            return true;
        }
        //后序遍历最后一个元素是根节点
        int root = sequence[right];
        int i = left;
        //找到第一个比根节点大的数,即右子树后序遍历的第一个节点
        while(i < right) {
            if(sequence[i] > root) {
                break;
            }
            i++;
        }
        //i左边都小于根节点
        int j = left;
        while(j < i) {
            if(sequence[j] > root) {
                return false;
            }
            j++;
        }
        //i右边都大于根节点
        while(j < right) {
            if(sequence[j] < root) {
                return false;
            }
            j++;
        }
        //对左右子树分别递归,判断是否符合条件
        return recur(sequence, left, i - 1) && recur(sequence, i, right - 1);
    }
}

优化:第一个循环和第二个循环可以合并

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length == 0) {
            return false;
        }
        return recur(sequence, 0, sequence.length - 1);
    }
    boolean recur(int[] sequence, int left, int right) {
        if(left >= right) {
            return true;
        }
        //后序遍历最后一个元素是根节点
        int root = sequence[right];
        int i = left;
        //找到第一个比根节点大的数
        while(i < right && sequence[i] < root) {
            i++;
        }
        int mid = i;
        //i右边都大于根节点
        while(i < right) {
            if(sequence[i] < root) {
                return false;
            }
            i++;
        }
        //对左右子树分别递归,判断是否符合条件
        return recur(sequence, left, mid - 1) && recur(sequence, mid, right - 1);
    }
}

思路2:栈+逆序遍历

后序遍历序列的逆序即为根节点->右节点->左节点。例如[4,8,6,12,16,14,10]

  1. 根节点为10,入栈
  2. 14>10,则为10的右节点,入栈
  3. 16>14,则为14的右节点,入栈,栈中元素为[10,14,16]
  4. 12不断和栈顶元素比较,直到12大于栈顶元素[10],假设栈顶之上保存了上一个出栈的元素为root=14,则12是root的左节点,入栈,此时栈中元素为[10,12]
public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length == 0) {
            return false;
        }
        Stack<Integer> stack = new Stack<>();
        int i = sequence.length - 1;
        int root = Integer.MAX_VALUE;
        while(i >= 0) {
            if(sequence[i] > root) {
                return false;
            } else {
                while(!stack.isEmpty() && stack.peek() > sequence[i]) {
                    root = stack.pop();
                }
                stack.push(sequence[i]);
            }
            i--;
        }
        return true;
    }
}

思路3:栈

将序列从小到大排序,即得到二叉树的中序遍历结果,判断后序遍历序列是否是合法出栈序列

全部评论

相关推荐

哈哈哈,你是老六:百度去年裁员分评不好,赶紧弄点红包
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
10551次浏览 93人参与
# 你的实习产出是真实的还是包装的? #
1855次浏览 42人参与
# 巨人网络春招 #
11324次浏览 223人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7568次浏览 43人参与
# 简历第一个项目做什么 #
31666次浏览 335人参与
# 重来一次,我还会选择这个专业吗 #
433448次浏览 3926人参与
# 米连集团26产品管培生项目 #
5940次浏览 216人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187111次浏览 1122人参与
# 牛客AI文生图 #
21423次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152352次浏览 888人参与
# 研究所笔面经互助 #
118899次浏览 577人参与
# 简历中的项目经历要怎么写? #
310220次浏览 4210人参与
# AI时代,哪些岗位最容易被淘汰 #
63649次浏览 823人参与
# 面试紧张时你会有什么表现? #
30506次浏览 188人参与
# 你今年的平均薪资是多少? #
213077次浏览 1039人参与
# 你怎么看待AI面试 #
180039次浏览 1255人参与
# 高学历就一定能找到好工作吗? #
64324次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76488次浏览 374人参与
# 我的求职精神状态 #
448046次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363380次浏览 2638人参与
# 腾讯音乐求职进展汇总 #
160641次浏览 1111人参与
# 校招笔试 #
470896次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务