zoukankan      html  css  js  c++  java
  • 109. Convert Sorted List to Binary Search Tree

    该题需要用一个递增的链表构建一个二叉树。数组的中位数为数的根节点,以中位数为分界,可以将数组分成左子数组以及右子数组,那么左边数组的中位数是左节点的值,右边数组的中位数为右节点的值,以此类推。

    所以我们可以想到,首先需要将链表转换为数组,然后直接定位中位数的值为根节点的值,并通过递归的方法分别构造左子树以及右子树。

    代码如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 /**
    10  * Definition for a binary tree node.
    11  * public class TreeNode {
    12  *     int val;
    13  *     TreeNode left;
    14  *     TreeNode right;
    15  *     TreeNode(int x) { val = x; }
    16  * }
    17  */
    18 class Solution {
    19     public TreeNode sortedListToBST(ListNode head) {
    20         if(head == null){
    21             return null;
    22         }
    23         
    24         ListNode temp = head;
    25         int nodenum = 0;
    26         while(temp != null){
    27             temp = temp.next;
    28             nodenum ++;
    29         }
    30         
    31         int[] temparray = new int[nodenum];
    32         temp = head;
    33         
    34         for(int i = 0 ; i < nodenum ; i++){
    35             temparray[i] = temp.val;
    36             temp = temp.next;
    37         }
    38         
    39         TreeNode root = new TreeNode(0);
    40         helper(root, temparray, 0, nodenum - 1);
    41         
    42         return root;
    43     }
    44     
    45     private void helper(TreeNode res, int[] arr, int lindex, int rindex){
    46         
    47         int pos = (rindex - lindex + 1)%2 == 0 ? (rindex + lindex + 1)/2:(rindex + lindex)/2;
    48         res.val = arr[pos];
    49         
    50         if(pos - 1  >= lindex){
    51             res.left = new TreeNode(0);
    52             helper(res.left, arr, lindex, pos - 1);
    53         }
    54         
    55         if( rindex >= pos + 1){
    56             res.right = new TreeNode(0);
    57             helper(res.right, arr, pos + 1, rindex);
    58         }
    59     }
    60 }

     

    怎么才能不需要额外空间就能够实现二叉树的构建呢?参考了一下以下链接,

    https://blog.csdn.net/worldwindjp/article/details/39722643

    分别有自顶向下以及自底向上的构建方法。

    贴上方法一的代码:

     1     public class Solution {  
     2         ListNode getLeftNodeFromList(ListNode head) {  
     3             ListNode next = head;  
     4             ListNode current = head;   
     5             ListNode pre = head;  
     6       
     7             while(next!=null) {  
     8                 next = next.next;  
     9                 if(next==null) {  
    10                     break;  
    11                 }  
    12                 next = next.next;  
    13                 if(next==null) {  
    14                     break;  
    15                 }  
    16                 pre = head;  
    17                 head = head.next;  
    18             }  
    19             return pre;  
    20         }  
    21           
    22           
    23         public TreeNode sortedListToBST(ListNode head) {  
    24             if(head==null) {  
    25                 return null;  
    26             }  
    27             if(head.next==null) {  
    28                 return new TreeNode(head.val);  
    29             }  
    30               
    31             ListNode left = getLeftNodeFromList(head);  
    32             ListNode mid = left.next;  
    33             TreeNode root = new TreeNode(mid.val);  
    34             left.next     = null;  
    35             root.left     = sortedListToBST(head);  
    36             root.right    = sortedListToBST(mid.next);  
    37             return root;  
    38         }  
    39     }  

    不需要额外空间的关键在于能够找到在链表当中获取中位数的方法,主要思路为定义了两个指针,在遍历链表的时候,一个指针每次循环遍历两个节点,一个只是遍历一个,当遍历两个的指针为空的时候,另一个指针就会指向链表的中间节点。

    利用这种思路,首先找出链表中中间节点的前一个节点,然后使用中间节点的值构造根节点;接着将链表分拆成左边的链表以及右边的链表,中间节点的前一个节点的next定义为null,那么中间节点的next就指向了右边的链表,以此类推。

    贴上方法二的代码:

     1     public class Solution {  
     2         static ListNode currentHead = null;  
     3         TreeNode buildTree(int start, int end) {  
     4             if(start>end) {  
     5                 return null;  
     6             }  
     7             int mid = start + (end - start)/2;  
     8             TreeNode left = buildTree(start, mid-1);  
     9             TreeNode root = new TreeNode(currentHead.val);  
    10             root.left = left;  
    11             currentHead = currentHead.next;  
    12             root.right = buildTree(mid + 1, end);  
    13             return root;  
    14         }  
    15           
    16         public TreeNode sortedListToBST(ListNode head) {  
    17             if(head==null) {  
    18                 return null;  
    19             }  
    20             currentHead = head;  
    21             int len = 0;  
    22             while(head!=null) {  
    23                 len++;  
    24                 head = head.next;  
    25             }  
    26               
    27             return buildTree(0, len-1);  
    28         }  
    29     }  

    方法二是先构造左子树,通过递归,首先找出链表第一个节点在树中的位置,找到后用链表节点的值构造树节点,接着寻找链表第二个节点在树中的位置,以此类推。

     

     

    END

     

  • 相关阅读:
    Reading papers_2(与GMM相关,ing...)
    Matlab DIP(瓦)ch11表示与描述练习
    HMM学习笔记_1(从一个实例中学习DTW算法)
    Matlab DIP(瓦)ch10图像分割练习
    前景检测算法_2(帧差法1)
    目标跟踪学习笔记_3(particle filter初探2)
    基础学习笔记之opencv(2):haartraining前将统一图片尺寸方法
    Reading papers_5(与human activity analysis综述相关,ing...)
    总结系列_4(C++知识学习,续...)
    HMM学习笔记_2(从一个实例中学习HMM前向算法)
  • 原文地址:https://www.cnblogs.com/sssysukww/p/8862971.html
Copyright © 2011-2022 走看看