Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
Analyse: the core idea of this problem is the same as Convert Sorted Array to Binary Search Tree. For a list, it's hard to access the elements randomly, we have to compute the list's length and sequencely locate a specific element.
Trial 1: Construct a function s.t. for a given index, it returns find its corresponding ListNode.
NA: TIME LIMITED.
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 /** 10 * Definition for a binary tree node. 11 * struct TreeNode { 12 * int val; 13 * TreeNode *left; 14 * TreeNode *right; 15 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 * }; 17 */ 18 class Solution { 19 public: 20 TreeNode* sortedListToBST(ListNode* head) { 21 if(!head) return NULL; 22 23 int len = 0; //length of the list 24 ListNode* move = head; 25 while(move){ 26 move = move->next; 27 len++; 28 } 29 return construct(head, 0, len - 1); 30 } 31 32 TreeNode* construct(ListNode* head, int low, int high){ 33 if(low > high) return NULL; 34 35 int mid = (low + high) / 2; 36 ListNode* targetListNode = nodeAtIndex(head, mid); 37 TreeNode* root = new TreeNode(targetListNode->val); 38 if(low == high) return root; 39 40 root->left = construct(head, low, mid - 1); 41 root->right = construct(head, mid + 1, high); 42 43 return root; 44 } 45 46 ListNode* nodeAtIndex(ListNode* head, int index){ 47 if(index < 0 || !head) return NULL; 48 49 ListNode* move = head; 50 int count = 0; //index of the first node in the list is 0 51 while(count != index){ 52 move = move->next; 53 count++; 54 } 55 return move; 56 } 57 };
I found a similiar solution in http://www.cnblogs.com/remlostime/archive/2012/10/29/2744805.html. But it improved the locating process. Thus it AC.
Trial 2: Then I wanna be opportunistic. I pushed every value in the list into a vector and tried to use the original code I wrote before. HAHAHA
Runtime: 32ms.
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 /** 10 * Definition for a binary tree node. 11 * struct TreeNode { 12 * int val; 13 * TreeNode *left; 14 * TreeNode *right; 15 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 * }; 17 */ 18 class Solution { 19 public: 20 TreeNode* sortedListToBST(ListNode* head) { 21 if(!head) return NULL; 22 23 vector<int> vec; //convert this question to a simpler one ^_^ 24 ListNode* move = head; 25 while(move){ 26 vec.push_back(move->val); 27 move = move->next; 28 } 29 30 return convert(vec, 0, vec.size() - 1); 31 } 32 TreeNode* convert(vector<int>& nums, int low, int high){ 33 if(low > high) return NULL; 34 35 int mid = (low + high) / 2; 36 TreeNode* root = new TreeNode(nums[mid]); 37 if(low == high) return root; 38 39 root->left = convert(nums, low, mid - 1); 40 root->right = convert(nums, mid + 1, high); 41 42 return root; 43 } 44 };
Trial 3: A recursion solution evolved from trail 1. First find the mid node, then recursively do the left and right part.
Runtime: 28ms.
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 /** 10 * Definition for a binary tree node. 11 * struct TreeNode { 12 * int val; 13 * TreeNode *left; 14 * TreeNode *right; 15 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 * }; 17 */ 18 class Solution { 19 public: 20 TreeNode* sortedListToBST(ListNode* head) { 21 if(!head) return NULL; 22 23 int len = 0; //length of the list 24 ListNode* move = head; 25 while(move){ 26 move = move->next; 27 len++; 28 } 29 return construct(head, 0, len - 1); 30 } 31 32 TreeNode* construct(ListNode* &head, int low, int high){ 33 if(low > high) return NULL; 34 35 int mid = (low + high) / 2; 36 TreeNode* leftSubtree = construct(head, low, mid - 1); 37 TreeNode* root = new TreeNode(head->val); 38 root->left = leftSubtree; 39 head = head->next; //the right subtree follows the current mid node. 40 TreeNode* rightSubtree = construct(head, mid + 1, high); 41 root->right = rightSubtree; 42 43 return root; 44 } 45 };