【细节】剑指offer——面试题24:二叉搜索树的后序遍历序列

力扣

Python

class Solution:
    def verifyTreeOrder(self, postorder: List[int]) -> bool:
        if not postorder:
            return True
        root_val = postorder[-1]
        first_big_idx = -1
        for i, val in enumerate(postorder):
            if val > root_val:
                first_big_idx = i
                break
        left_arr = postorder[0: first_big_idx]
        right_arr = postorder[first_big_idx: len(postorder)-1]
        cur_res = True
        if right_arr:
            cur_res = root_val < min(right_arr)
        return cur_res and self.verifyTreeOrder(left_arr) and self.verifyTreeOrder(right_arr)

20231129重做

class Solution {
    public boolean verifyTreeOrder(int[] postorder) {
        if (postorder.length < 2) {
            return true;
        }

        return recur(postorder, 0, postorder.length - 1);
    }

    public boolean recur(int[] postorder, int start, int end) {
        if (start == -1 || end == -1 || start >= end) {
            return true;
        }
        int rootVal = postorder[end];
        int leftStart = -1, leftEnd = -1, rightStart = -1, rightEnd = -1;
        for (int k = start; k < end; ++k) {
            if (postorder[k] < rootVal) {
                if (leftStart == -1) {
                    leftStart = k;
                }
                leftEnd = k;
            } else {
                break;
            }
        }
        rightStart = leftEnd == -1 ? start : leftEnd + 1;
        for (int k = rightStart; k < end; ++k) {
            if (postorder[k] < rootVal) {
                return false;
            }
        }
        rightEnd = end - 1;

        return recur(postorder, leftStart, leftEnd) && recur(postorder, rightStart, rightEnd);
    }
}

思路1

20231116:两边夹更新索引,判断是否一致

class Solution {
    public boolean verifyTreeOrder(int[] postorder) {
        return myFunc(postorder, 0, postorder.length - 1);
    }

    public boolean myFunc(int[] postorder, int startIndex, int endIndex) {
        if (startIndex >= endIndex) {
            return true;
        }
        int leftEnd = startIndex - 1, rightStart = endIndex; // 这个定义特别重要!!!
        for (int i = startIndex; i < endIndex; ++i) {
            if (postorder[i] < postorder[endIndex]) {
                leftEnd = i;
            } else {
                break;
            }
        }
        for (int i = endIndex - 1; i >= startIndex; --i) {
            if (postorder[i] > postorder[endIndex]) {
                rightStart = i;
            } else {
                break;
            }
        }
        
        return (leftEnd + 1 == rightStart) 
                && myFunc(postorder, startIndex, leftEnd) 
                && myFunc(postorder, rightStart, endIndex - 1);

    }
}

思路2

传统思路

class Solution {
    public boolean verifyTreeOrder(int[] postorder) {
        if (postorder.length == 0) {
            return true;
        }
        List<Integer> postList = new ArrayList<>();
        for (int i : postorder) {
            postList.add(i);
        }

        return myFunc(postList);
    }

    public boolean myFunc(List<Integer> list) {
        int size = list.size();
        if (size <= 1) {
            return true;
        }
        int rootVal = list.get(size - 1);
        List<Integer> leftList = new ArrayList<>();
        List<Integer> rightList = new ArrayList<>();
        int rightStartIndex = -1; // 右子树起始索引
        for (int i = size - 2; i >= 0; --i) {
            if (list.get(i) > rootVal) {
                rightStartIndex = i;
            } else if (list.get(i) < rootVal) {
                break;
            } else {
                return false;
            }
        }
        int leftEndIndex = rightStartIndex == -1 ? size - 2 : rightStartIndex - 1;
        for (int i = 0; i <= leftEndIndex; ++i) {
            if (list.get(i) >= rootVal) {
                return false;
            }
        }
        if (rightStartIndex > 0) {
            leftList = list.subList(0, rightStartIndex);
            rightList = list.subList(rightStartIndex, size - 1);
        } else if (rightStartIndex == 0) {
            rightList = list.subList(rightStartIndex, size - 1);
        } else if (rightStartIndex == -1) {
            leftList = list.subList(0, size - 1);
        }

        return myFunc(leftList) && myFunc(rightList);

    }
}

##Solution1:
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
参考网址:https://www.nowcoder.com/profile/8378038/codeBookDetail?submissionId=17463800

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        return bst(sequence,0,sequence.size()-1);
    }
    bool bst(vector<int> &sequence,int begin,int end){ //整型参数为vector下标
        if(sequence.empty()||begin>end)
            return false;
        int root=sequence[end];
        int i=begin;
        for(;i<end;++i) //从左向右查数,以确定边界。
           //故已经循环过的数字肯定是根结点的左子树,
           //故在下一个for循环中秩序判断边界向右的数字是否是右子树中的值即可
            if(sequence[i]>root)//i坐标为右子树第一个节点
                break;
        for(int j=i;j<end;++j) //如果上个for循环是从右向左查数来确定边界,
              //则在该for循环中只需判断边界向左中的数是否是左子树中的值即可
            if(sequence[j]<root)
                return false;
        bool left=true;
        if(i>begin) //若i==begin,则左子树为空,此时左子树为默认的true
            left=bst(sequence,begin,i-1);
        bool right=true;
        if(i<end-1) //若i==end-1,则右子树为一个点,此时右子树为默认的true
            right=bst(sequence,i,end-1);
        return left&&right;
    }
};

#Solution2:
2018年9月1日重做

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        return bst(sequence, 0, sequence.size() - 1);
    }
    bool bst(vector<int> &sequence, int begin, int end) { //整型参数为vector下标
        if (sequence.empty() || begin > end)
            return false;
        int root = sequence[end]; //根结点
        int i = begin;
        //找到左右子树的分割点
        for (; i < end; ++i) 
            if(sequence[i] > root) //i坐标为右子树第一个节点
                break;
        //右子树结点中若比根结点小 直接返回false
        for (int j = i; j < end; ++j)
            if(sequence[j] < root) 
                return false;
        bool left = true;
        if (i > begin) //若i==begin,则左子树为空,此时左子树为默认的true
            left = bst(sequence, begin, i - 1);
        bool right = true;
        if(i < end - 1) //若i==end-1,则右子树为一个点,此时右子树为默认的true
            right = bst(sequence, i, end - 1);
        return left&&right;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值