LeetCode劍指offer Q36 二叉搜索樹與雙向鏈表 java 雙百

思路

要將一個二叉搜索樹轉化爲升序的循環雙向鏈表,很明顯使用中序遍歷能獲得升序。然後思考怎樣改造中序遍歷能夠構建循環雙向鏈表且不需要新建結點。考慮到雙向,則肯定需要保存前驅節點,因此如下設置:

  1. 新建pre、head兩個指針,pre指向前一個工作節點,head指向循環雙向鏈表的頭結點。
  2. 在中序遍歷過程中 root.left=pre; pre.right=right; 每次訪問一個節點時,爲它的前驅設置後繼。
  3. 當pre爲null時說明訪問到了二叉樹的最小節點,應該作爲頭節點進行保存 head=root;
  4. 最後中序遍歷完了之後。不能夠忘記將最後一個結點的後繼和head的前驅設置好。而此時pre便是指向最後一個結點的,所以可以直接:head.left=pre; pre.right=head;

代碼

package algorithm.jianzhiOffer;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class Node2 {
    public int val;
    public Node2 left;
    public Node2 right;

    public Node2() {}

    public Node2(int _val) {
        val = _val;
    }

    public Node2(int _val,Node2 _left,Node2 _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
public class Q36 {

    //0ms。改造完的高效率解法
    Node2 pre=null,head=null;
    public Node2 treeToDoublyList(Node2 root) {
        if(root==null) return null;

        inOrder(root);
        pre.right=head;
        head.left=pre;
        return head;
    }
    void inOrder(Node2 root){
        if(root==null) return;
        inOrder(root.left);
        root.left=pre;
        if(pre!=null) pre.right=root;
        else head=root;
        pre=root;
        inOrder(root.right);
    }


//2ms  未改造的低效率解法
     List<Node2> list=new ArrayList();
    public Node2 treeToDoublyList2(Node2 root) {
        if(root==null) return null;

        inOrder2(root);

         int size=list.size();
         if(size==1) {
             root.left=root.right=root;
             return root;
         }
         list.get(0).right=list.get(1);
         list.get(0).left=list.get(size-1);
         list.get(size-1).left=list.get(size-2);
         list.get(size-1).right=list.get(0);
         if(size==2){
             return list.get(0);
         }
         for(int i=1;i<size-1;i++){
                 list.get(i).right=list.get(i+1);
                 list.get(size-i-1).left=list.get(size-i-2);
         }
         return list.get(0);
    }
    void inOrder2(Node2 root){
        if(root==null) return;
        inOrder2(root.left);
        list.add(root);
        inOrder2(root.right);
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章