Convert Sorted double linked List to Binary Search Tree

Convert Sorted double linked  List to Binary Search Tree
In place

閆老師講的這兩個 答案 是把他 當作 single linked list了, 可是對於double linked list , 也適用






base case : at least three nodes , other wise mid.next and mid.next.next NPE


NOT TESTED YET 

小班文檔


Solution one:

先處理 head.next =null
And head.next.next = null


閆老師也不是一上來就知道怎麼作, 也是從 induction 作, 把general 的 case 處理掉
而後再回頭看 base case ,分別從 size = 0, 1,2, 3 看起, 有沒有越界, 之類的

是一步步分析出來的。 

如今作tag和 面經題, 也是要本身一步步分析出來, 面試的時候 靠的是以前準備時的功底, 不是
當場現想,或者無腦背答案






// one is list node . Another one Is tree node 




Draw the recursion tree
N  find the middle node on each level in total. There is logn levels 
  So   O(NLOGN) in total 

 

class Solution {
    public TreeNode ddlToBST(ListNode head) {
      // base case 
      if(head == null) return null;
      if(head.next == null) return ..;
      if(head.next.next == null) return ..;
      
      // recursion + induction rule
      ListNode mid = findMiddle(head);
      TreeNode root = new TreeNode(mid.next.val);
      ListNode next = mid.next.next;
      mid.next.next = null;
      mid.next = null;
      root.left = ddlToBST(head);
      root.right = ddlToBST(next);
      return root;
    }
}




Solution two:
一邊構建 left subtree 一邊對這個linked list 進行 
遍歷

time: o(n)





Convert Sorted double linked  List to Binary Search Tree
In place
仍是不理解這個作法

Solution two:
一邊構建 left subtree 一邊對這個linked list 進行 
遍歷

time: O(n)

// get the length of the list 
public TreeNode (ListNode head){
  int length = length(head);
  
  // construct the tree recursively
  return construct(0, length - 1);
}

ListNode curInOrder = head;
private TreeNode construct(int start, int end){
  // base case
  if(start > end) return null;
  
  int mid = start + (end - start) / 2;
  TreeNode left = construct(start, mid - 1);
  TreeNode root = new TreeNode(curInOrder.val);
  
  curInOrder = curInOrder.next;
  root.left = left;
  
  root.right = construct(mid + 1, end);
  return root;
 
}

private int length(ListNode head){
  int count = 0;
  ListNode pointer = head;
  while(pointer != null){
    count +=1;
    pointer = pointer.next;
  }
  return count;
}




///////
本身寫的 solution 1 

// later I can test my code using this node class, and treat tree node and list node as the same 
class Node {
    public int val;
    public Node left;
    public Node right;

    public Node() {}

    public Node(int _val,Node _left,Node _right) {
        val = _val;
        left = _left;
        right = _right;
    }
}










public TreeNode dllToBST(ListNode head){
  // base case. when the size of the linked list is 0, 1, 2 
  // when the size is 0
  if(head == null){
    return null;
  }
  
  // when the size is 1
  if(head.next = null){
    return new TreeNode(head.val);
  }
  
  // when the size of the linked list is 2 
  if(head.next.next = null){
    TreeNode next = new TreeNode(head.next.val);
    TreeNode root = new TreeNode(head.val);
    root.right = next;
    return root;
  }
  
  // recursion + induction
  ListNode middle = findMid(head);
  TreeNode root = new TreeNode(middle.val);
  ListNode next = middle.next;
  ListNode prev = middle.prev;
  
  middle.next = null;
  prev.next = null;
  
  root.left = dllToBST(head);
  root.right = dllToBST(next);
  
  return root;
}


private ListNode findMid(ListNode head){
  // base case : 0 1 2 3 
  // size 0, 1, 2 wont be here because they have taken care of 
  // in the base case of the above func
  ListNode tail = head.prev;
  
  ListNode fast = head;
  ListNode slow = head;
  
  while(fast != tail && fast.next != tail){
    fast = fast.next.next;
    slow = slow.next;
  }
  
  return slow;
}

 把本身寫的solution 1 和 閆老師寫的solution2 都弄懂,會寫。 node

bst變double linked list。recursion秒了,而後第一個follow up是把雙鏈表變回去,要求balance。第二個follow up是在犧牲空間複雜度的狀況下如何優化時間,想了個時間O(n)的思路,面試

時間空間複雜度會分析優化

相關文章
相關標籤/搜索