LeetCode 109——有序鏈表轉化二叉搜索樹

1. 題目

2. 解答

2.1. 方法一

LeetCode 108——將有序數組轉化爲二叉搜索樹 中,咱們已經實現了將有序數組轉化爲二叉搜索樹。所以,這裏,咱們能夠先遍歷一遍鏈表,將節點的數據存入有序數組中,而後再將有序數組轉化爲二叉搜索樹便可。數組

class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head) {
        
        vector<int> nums;
        
        while (head != NULL)
        {
            nums.push_back(head->val);
            head = head->next;
        }
        
        return sortedArrayToBST(nums, 0, nums.size()-1);
    }
    
    TreeNode* sortedArrayToBST(vector<int>& nums, int begin, int end) {
        
        if (end < begin) return NULL; // 數組爲空
        int mid = begin + (end - begin) / 2;
                
        TreeNode * tree = new TreeNode(nums[mid]); // 中值做爲根節點
        tree->left = sortedArrayToBST(nums, begin, mid-1); // 左子樹
        tree->right = sortedArrayToBST(nums, mid+1, end); // 右子樹
        
        return tree;
    }
};
複製代碼
2.2. 方法二

將有序數組轉化爲二叉搜索樹的核心思想就是找到數組的中間數據,以此爲根節點,而後再遞歸創建左右子樹。所以,藉助於 LeetCode 876——鏈表的中間結點 中的思想,咱們能夠快速地找到鏈表的中間節點,而後再以中間節點先後的兩個子鏈分別創建左右子樹便可。ui

以下圖所示,當 slow 指針指向中間節點時,last 指針指向中間節點的上一個節點,slow->next 是右子鏈的頭結點,而將 last->next 指向 NULL 後,左子鏈的頭節點即爲 head。spa

此外,要注意一種特殊狀況,當只有一個節點時,此時 last、slow、fast 都指向這個節點,那麼左子鏈此時應爲空.net

class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head) {
        
        ListNode* last = head;
        ListNode* slow = head;  
        ListNode* fast = head;  

        // 循環結束時慢指針指向中間結點
        while(fast && fast->next)   
        {
            last = slow;
            slow = slow->next; 
            fast = fast->next->next;
        }
        
        if (slow == NULL) return NULL;
                
        TreeNode * tree = new TreeNode(slow->val); // 中值做爲根節點
        
        if (last == slow) tree->left = NULL;
        else
        {         
            last->next = NULL;
            tree->left = sortedListToBST(head); // 左子樹
        }
        tree->right = sortedListToBST(slow->next); // 右子樹
        
        return tree;
        
    }
    
};
複製代碼

獲取更多精彩,請關注「seniusen」! 指針

相關文章
相關標籤/搜索