108. 将有序数组转换为二叉搜索树
难度:简单。
标签:二叉搜索树,数组,分治。
正确解法:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
TreeNode* get(vector<int> nums, int left, int right){
if(left > right)return nullptr;
else if(left == right){
TreeNode* cur = new TreeNode(nums[left]);
return cur;
}
int mid = (left + right + 1) / 2;
TreeNode* cur = new TreeNode(nums[mid]);
cur->left = get(nums, left, mid - 1);
cur->right = get(nums, mid + 1, right);
return cur;
}
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return get(nums, 0, nums.size() - 1);
}
};
结果:
怎么好慢,明明方法都差不多。
109. 有序链表转换二叉搜索树
难度:中等。
标签:二叉搜索树,链表,分治。
难点在于链表不像数组那样可以按索引访问,也不能直接获取其大小。
刚开始想到的是用快慢指针找其中间的点。
写这个解法,出现了很多小问题。
正确解法:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
ListNode* getMiddle(ListNode* node, ListNode* endNode){
ListNode* fast = node, *slow = node;
while(fast != endNode && fast->next != endNode){
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
TreeNode* get(ListNode* beginNode, ListNode* endNode){
if(beginNode == nullptr || beginNode == endNode)return nullptr;
ListNode* mid = getMiddle(beginNode, endNode);
TreeNode* cur = new TreeNode(mid->val);
cur->left = get(beginNode, mid);
cur->right = get(mid->next, endNode);
return cur;
}
public:
TreeNode* sortedListToBST(ListNode* head) {
return get(head, nullptr);
}
};
结果:
官方题解的方法二更快。
链表本来就是平衡二叉树的中序遍历,将中序遍历结合起来使用,按链表的顺序来构建二叉树,这样不需要使用快慢指针找中间的node,开始计算链表长度,使用链表的索引来完成。
注意build函数第一个参数,要加取地址符,对单纯指针变量本身的修改无法作用到原指针变量,所以需要通过引用来实现修改指针变量。
正确解法:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
int getLength(ListNode* head){
ListNode* node = head;
int len = 0;
while(node->next != nullptr){
len++;
node = node->next;
}
return len;
}
TreeNode* build(ListNode*& node, int left, int right){
if(left > right)return nullptr;
int mid = (left + right + 1) / 2;
TreeNode* cur = new TreeNode();
cur->left = build(node, left, mid - 1);
cur->val = node->val;
node = node->next;
cur->right = build(node, mid + 1, right);
return cur;
}
public:
TreeNode* sortedListToBST(ListNode* head) {
if(head == nullptr)return nullptr;
int len = getLength(head);
return build(head, 0, len);
}
};
结果: