文章目录
Leetcode109
1.题目描述
2.解决方案
解法一:快慢指针递归法
思路
总结
1.分析只剩一两个节点的情况,也就是递归到最深层的时候才能更好的判断一些极限情况应该如果设置,而不是看别人或者题解是怎么处理的,比如这两个片段关于极限情况的处理:
第一个while中当你分析到最后有可能出现left->next= =right的情况,加上左闭右开的原则,也就是只剩一个节点,mid就需要返回这个节点,这是你再去看while里应该放什么判断条件,就很清晰了。
第二个if的判断中 当你分析到最后一定会出现left->next= =right的情况,加上左闭右开的原则,也就是说这一段链表中只有一个节点,这时候mid一定是返回left这个节点,也只有这个节点了,然递归调用(left,mid)就会出现 left= =right 的情况,我们分析当然知道这时候需要返回nullptr,因为这个节点是个叶子节点,所以有了第二个片段。
//while (fast!=right){
//while (fast->next!=right){
while (fast!=right && fast->next!=right){
fast=fast->next->next;
slow=slow->next;
}
//if (left== nullptr) return nullptr;
if(left==right) return nullptr;
2.快慢指针在链表中非常常用请记住,尤其是再需要确定位置一些用途上。
3.需要用链表表示一些范围,左闭右开原则是一个很好的选择,在思路图中已经标出好处。
代码实现
class Solution {
public:
//全程左闭右开原则!!!!
ListNode* getMidPoint(ListNode* left,ListNode* right){
ListNode* fast=left;
ListNode* slow=left;
//while (fast!=right){
while (fast!=right && fast->next!=right){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
TreeNode* buildTree(ListNode* left,ListNode* right){
//if (left== nullptr) return nullptr;
if(left==right) return nullptr;
TreeNode* root=new TreeNode();
ListNode* mid=getMidPoint(left,right);
root->val=mid->val;
root->left=buildTree(left,mid);
root->right=buildTree(mid->next,right);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
return buildTree(head, nullptr);
}
};
复杂度分析
解法二:分治 + 中序遍历优化(我还没看)
class Solution {
public:
int getLength(ListNode* head) {
int ret = 0;
for (; head != nullptr; ++ret, head = head->next);
return ret;
}
TreeNode* buildTree(ListNode*& head, int left, int right) {
if (left > right) {
return nullptr;
}
int mid = (left + right + 1) / 2;
TreeNode* root = new TreeNode();
root->left = buildTree(head, left, mid - 1);
root->val = head->val;
head = head->next;
root->right = buildTree(head, mid + 1, right);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
int length = getLength(head);
return buildTree(head, 0, length - 1);
}
};