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——連結串列的中間結點 中的思想,我們可以快速地找到連結串列的中間節點,然後再以中間節點前後的兩個子鏈分別建立左右子樹即可。
如下圖所示,當 slow 指標指向中間節點時,last 指標指向中間節點的上一個節點,slow->next 是右子鏈的頭結點,而將 last->next 指向 NULL 後,左子鏈的頭節點即為 head。
此外,要注意一種特殊情況,當只有一個節點時,此時 last、slow、fast 都指向這個節點,那麼左子鏈此時應為空。
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」!