• 二叉搜索树与双向链表


    来源: 牛客网

    题目描述

    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
    举例如下图:

    插图来自《剑指offer》

    可见,二叉搜索树的中序遍历即是一个有序数组。然后动手写代码,但是让人苦恼的是牛客网给出的函数定义(我是javaer):

    /**
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
    
        public TreeNode(int val) {
            this.val = val;
    
        }
    
    }
    */
    public class Solution {
        public TreeNode Convert(TreeNode pRootOfTree) {
            
        }
    }

    按照一贯做法,此题要返回排序双向链表的头节点。

    加上中序遍历的函数后:

    public class Solution {
        public TreeNode Convert(TreeNode pRootOfTree) {
            if(pRootOfTree==null) return null;
            inOrder(pRootOfTree);
            ……
            ……
            }
        }
    
        public void inOrder(TreeNode node){
            if(node!=null){
                inOrder(node.left);
                print(node); // 访问此节点
                inOrder(node.right);
            } 
        }
    }

    inOrder 函数没有返回值,因此必须在Solution 类中定义一个域来存储中序遍历序列。之前没有这样写过,不知道牛客网的测试程序是什么情况。查看《剑指offer》中,是以引用的形式将Convert函数中的一个TreeNode结构体指针传递给ConvertNode函数(相当于上面的inOrder函数),这样在ConvertNode函数中才能修改Convert函数中变量的内容。java中没有这种写法。

    我尝试在Solution类中定义一个ArratList<TreeNode>存储中序遍历序列,然后牛客网接受了这种写法。AC代码如下:

    解释一下题目中“要求不能创建任何新的结点”这句话,意思是用new 关键字即调用了TreeNode类构造函数,这才叫创建了一个新的节点。

    下面代码中的ArrayList<TreeNode>只是一个容器,用来辅助存储这些树节点,然后在遍历的时候调整节点的左右指针,整个过程中没有创建新节点。因此是符合题目要求的。

     1 import java.util.*;
     2 /**
     3 public class TreeNode {
     4     int val = 0;
     5     TreeNode left = null;
     6     TreeNode right = null;
     7 
     8     public TreeNode(int val) {
     9         this.val = val;
    10 
    11     }
    12 
    13 }
    14 */
    15 public class Solution {
    16     ArrayList<TreeNode> l = new ArrayList<TreeNode>();
    17     public TreeNode Convert(TreeNode pRootOfTree) {
    18         if(pRootOfTree==null) return null;
    19         inOrder(pRootOfTree);
    20         if(l.size()==1) return l.get(0);
    21         else {
    22             l.get(0).right=l.get(1);
    23             for(int i=1; i<l.size()-1; ++i){
    24                 l.get(i).left=l.get(i-1);
    25                 l.get(i).right=l.get(i+1);
    26             }
    27 
    28             l.get(l.size()-1).left=l.get(l.size()-2);
    29             return l.get(0);
    30         }
    31     }
    32 
    33     public void inOrder(TreeNode node){
    34         if(node!=null){
    35             inOrder(node.left);
    36             l.add(node);
    37             inOrder(node.right);
    38         } 
    39     }
    40 }

    cd

  • 相关阅读:
    Leetcode 528. 按权重随机选择(中等) 前缀和数组+二分查找左侧边界
    Leetcode 494. 目标和(中等)回溯算法
    Datax使用SQL语句数据导入
    ps axjf 查看进程关系
    k8s CICD部署脚本
    1.18 kubeconfig ./admin.conf
    jenkins pipeline
    k8s jenkins CICD 流程
    cgroup driver
    docker 和contianerd区别
  • 原文地址:https://www.cnblogs.com/duanguyuan/p/5705923.html
Copyright © 2020-2023  润新知