Sword는 이진 검색 트리의 후속 순회 시퀀스 인 브러시 질문 (GZ23)에 대한 제안을 나타냅니다.

여기에 사진 설명 삽입
문제 해결 아이디어 :
O (nlogn)에서 O (n)으로, 재귀보다 효율적인 방법 : 상한 방법

방법 1 : 재귀 적 방법
주석을 읽고 재귀 적 분할 방법이 일반적으로 사용되는 것을 발견했습니다. 재귀는 간단하고 이해하기 쉽고 구현하기 쉽습니다. 먼저 트래버스하여 왼쪽 및 오른쪽 하위 트리의 경계 지점을 결정한 다음 재귀 적으로 만듭니다. 각각 두 개의 하위 트리에 대한 판단. 이제 재귀 방법의 시간 복잡도를 분석해 보겠습니다.

표준 완벽한 이진 검색 트리를 예로 들면 각 재귀 계층은 시퀀스를 순회하는 것을 포함합니다. 계층이 깊을수록 노드 수가 적지 만 (하위 트리의 루트 노드가 적음)이 감소는 미미합니다. , 여전히 n / 2 개의 노드가 있습니다 (완벽한 이진 트리의 i 번째 수준에있는 노드의 수는 그 위에있는 모든 노드의 합 + 1). 따라서 각 수준에서 재귀 메서드의 순회 비용은 O입니다. (n) 및 이진 트리의 경우 평균 재귀 수준 수는 O (logn)이므로 재귀 방법의 최종 복잡성은 O (nlogn)입니다.

방법 2 : 상한 방법
그래서 우리가 어쩔 수없이 욕심쟁이는 더 나은 방법이 있을까요? ? O (n), 심지어 O (logn)?

순회 순서가 정확하기 때문에 어떤 위치에서든 고의적으로 조작 할 수 있으므로 모든 요소를 ​​순회하여 정확성을 결정해야하므로 개인적으로이 문제의 시간 복잡도의 하한은 O ()가되어야한다고 생각합니다. 엔).

특히 이진 검색 트리의 주요 기능은 다음과 같습니다. 모든 하위 트리에 대해 "왼쪽 하위 트리 <루트 노드 <오른쪽 하위 트리"가 있으므로 루트 노드는 왼쪽 및 오른쪽 하위 트리의 값 범위를 제한합니다. 이진의 루트 루트 검색 트리는 왼쪽 하위 트리 값의 상한 (최대)과 동시에 오른쪽 하위 트리 값의 하한 (최소)입니다. 루트 노드에서 시작하여 아래로 내려 가면 상위 수준의 상위 노드 시퀀스가 ​​계속해서 하위 수준의 순회되지 않은 노드에 상한 및 하한 제약 조건을 형성합니다. 하위 수준 노드가이 제약 조건을 위반하지 않는 한 이면 합법적이며 그렇지 않으면 시퀀스가 ​​합법적이지 않습니다.

post-order traversal의 특성으로 인해 post-order traversal의 마지막 요소가 루트 노드이고 역방향 액세스는 루트에서 액세스하는 순서와 동일하므로 오른쪽에서 왼쪽으로 역순으로 주어진 시퀀스에 액세스 할 수 있습니다. to leaf 및 right to left., 루트에서 리프로, 상위 노드에서 제공하는 상한 및 하한 정보를 사용하여 자식 노드의 적법성을 판단 할 수 있습니다. 구체적인 단계는 다음과 같습니다.

현재 요소가 이전 요소이면 현재 요소가 이전 요소의 오른쪽 자식 일 수 있음을 의미합니다. 이때
현재 요소가 최대 상한 제약 조건을 위반하면 "왼쪽 하위 트리>가 있음을 의미합니다. 루트 "의 정의 검색 트리 위반 조상의 상황 (7 그림 4의 값을 변경하려고, 그때 아이들이 7이있을 것이다>를 조상 최대 제약 (5), 검색 트리 보류하지 않습니다)
그렇지 않으면 , 현재 요소는 이전 요소의 오른쪽 자식이고 현재 요소는 새 조상이됩니다. 노드는 후속 노드에 대한 제약을 제공
합니다. 현재 요소가 <이전 요소 인 경우 현재 요소가 a의 왼쪽 자식임을 의미합니다. 특정 조상 노드. 이때 :
조상 노드를 찾고 조상의 올바른 자식 트리 노드를 추가해야합니다. 모두 삭제 (올바른 하위 트리 구조가 결정되어 후속 노드에 대한 도움말을 제공 할 수 없기 때문에), 조상의 값 노드는 새로운 최대 상한 제약 조건
이되고 현재 요소는 새로운 조상 노드가되며 후속 노드에 대한 제약 조건을 계속 제공합니다.
여기에 사진 설명 삽입
따라서 결정된 조상 노드를 저장하기 위해 스택을 사용해야합니다. 노드가 결정되고 스택에 푸시하고 알고리즘이 현재 노드의 왼쪽 자식을 찾아야 할 때 팝업합니다.

복잡성 분석 : 팝핑이없는 경우 시퀀스는 오른쪽에서 왼쪽으로 액세스되고 정보는 차례로 스택으로 푸시되고 매번 스택의 맨 위에있는 값만 액세스됩니다. 복잡성은 O ( n); 팝핑의 경우., 동일한 노드가 스택에 반복적으로 팝 아웃되지 않기 때문에 최악의 경우 모든 노드가 팝 아웃 작업을 수행해야하고 복잡성이 O (n)에서 O (2n). 상수를 무시하면 알고리즘의 최종 시간 복잡도는 O (n)이고 공간 복잡도도 O (n)입니다.

import java.util.Stack;
public class Solution {
    
    
    public boolean VerifySquenceOfBST(int [] sequence) {
    
    
        if(sequence.length < 1){
    
    
            return false;
        }
        //roots栈中依次存放各层父辈节点的值
        //事先放入一个值避免对空栈进行判断
        Stack<Integer> roots = new Stack();
        roots.push(Integer.MIN_VALUE);
        int max = Integer.MAX_VALUE;
        for(int i = sequence.length-1; i > -1; i--){
    
    
            //如果当前节点超过max约束,那它必定不是二叉树
            if(sequence[i] >= max){
    
    
                return false;
            }
            //如果当前节点小于roots的栈顶,说明该节点是某个主辈的左孩子,需要找出这个祖辈
            //也就是不断出栈,利用二叉搜索树的特点,找出该祖辈,同时,该主辈也提供的新的max约束
            while(sequence[i] < roots.peek()){
    
    
                max = roots.peek();
                //为了找出给节点的祖辈而出栈
                roots.pop();
            }
            // 该节点成了新一代的祖辈节点,为后续节点判断自己的位置提供依据
            roots.push(sequence[i]);
        }
        return true;
    }
}

재판 : https://blog.nowcoder.net/n/8fe97e67996249ccbe71328d3a49c4af?f=comment

추천

출처blog.csdn.net/weixin_42118981/article/details/113288631