Algoritmo - (Árbol) BM41: genera la vista derecha del árbol binario

Descripción del título:
de acuerdo con el recorrido en orden anticipado y en orden del árbol binario, genere la vista derecha del árbol binario,
por ejemplo:
Preorden: [1,2,4,5,3]
En orden: [4,2,5,1,3]
entonces el árbol debería ser: Árbol binario
Resultado: [1,3,5]

Es muy interesante ver esta pregunta hoy. No es difícil, pero requiere mucho conocimiento de algoritmos. Utiliza tres algoritmos de entrevista de uso común: 1. Construya
un árbol basado en preorden y orden medio (medio)
2. Preorden del árbol Algoritmo transversal (simple)
3. DFS (primer algoritmo de búsqueda en profundidad) atraviesa un árbol por capa (medio)

rápido:

/*
 buid tree + DFS按层按层遍历
 */
func solve ( _ xianxu: [Int],  _ zhongxu: [Int]) -> [Int] {
    
    
    var tmpPre = xianxu     //前序遍历数组
    var tmpMid = zhongxu    //中序遍历数组
    let buildResTree = buildTree(xianxu: &tmpPre, left1: 0, right1: tmpPre.count - 1, zhongxu: &tmpMid, left2: 0, right2: tmpMid.count - 1)     //递归的去建树
    var rowTraResArray = Array<Array<Int>>.init()
    rowTra(treeNode: buildResTree,resArr: &rowTraResArray,floor: 1)     //得到树 按层遍历的数组
    var result = Array<Int>.init()
    for floorArr in rowTraResArray {
    
        //按层遍历的数组 每层的最后一个元素 就是右视图了
        result.append(floorArr.last!)
    }
    return result
}

/*
 根据前序数组、中序数组构建树
 xianxu : 前序遍历的数组
 left1  : 前序数组区间左
 right1 : 前序数组区间右
 zhongxu: 中序遍历的数组
 left2  : 中序数组区间左
 right2 : 中序数组区间右
 */
func buildTree (xianxu: inout [Int], left1: Int, right1: Int, zhongxu: inout [Int], left2: Int, right2: Int) -> TreeNode? {
    
    
    if(left1 > right1 || left2 > right2){
    
       //因为后面需要这四个数字进行递归,一旦不合法就无法继续递归
        return nil
    }
    //找到 root 在 中序 的index
    var rootIndex = -1
    for i in left2...right2{
    
    
        if(xianxu[left1] == zhongxu[i]){
    
    
            rootIndex = i
            break
        }
    }
    /*
     本级递归需要做的事情
     1、构建本级TreeNode节点
     2、找到本级TreeNode节点的左右子树的 前序、中序数组,递归下去
     */
    let treeNode = TreeNode.init(xianxu[left1], nil, nil)
    let leftTreeSize = rootIndex - left2        //本级TreeNode节点 左子树大小
    let rightTreeSize = right2 - rootIndex      //本级TreeNode节点 右子树大小
    //下面的递归 是本算法最不容易理解的地方、认真思考、就会收获良多
    treeNode.left = buildTree(xianxu: &xianxu, left1: left1 + 1, right1: left1 + leftTreeSize, zhongxu: &zhongxu, left2: left2, right2: rootIndex - 1)
    treeNode.right = buildTree(xianxu: &xianxu, left1: right1 - rightTreeSize + 1, right1: right1, zhongxu: &zhongxu, left2: rootIndex + 1, right2: right2)
    return treeNode
}

/*
 根据树按层遍历,得到遍历数组
 */
func rowTra (treeNode: TreeNode?, resArr: inout [[Int]], floor: Int) {
    
    
    if(treeNode == nil){
    
     return }
    if(resArr.count >= floor){
    
          //该层还未遍历完毕、继续遍历
        resArr[floor - 1].append(treeNode!.val)
    }else{
    
                              //需要新开一层
        var newArr = Array<Int>.init()
        newArr.append(treeNode!.val)
        resArr.append(newArr)
    }
    rowTra(treeNode: treeNode!.left, resArr: &resArr, floor: floor + 1)
    rowTra(treeNode: treeNode!.right, resArr: &resArr, floor: floor + 1)
}

Complejidad temporal: O (n), donde n es el número de nodos en el árbol binario, y el árbol binario se atraviesa dos veces Complejidad espacial:
O (n), se utiliza una matriz para almacenar los valores de los nodos atravesados ​​por capa Si los amigos necesitan lenguaje C, lenguaje
Java, la implementación del código de la versión se agregará más adelante.

Supongo que te gusta

Origin blog.csdn.net/weixin_44758107/article/details/127666551
Recomendado
Clasificación