LeetCode109. 有序链表转换二叉搜索树

//109. 有序链表转换二叉搜索树
/*
* 1、暴力做法:
*   先把链表转成数组
*   然后二分(dfs)遍历整个数组
*   过程中建立链表
*   时间复杂度:n
*   空间复杂度:n
* 2、快慢指针:
*   使用快慢指针找到链表的中间节点
*   然后用同样的方法处理两部分的链表:这种方式好像叫分治
*   时间复杂度:nlog(n)
*   空间复杂度:应该是常数,但是我看官方题解说的是log(n)
* 3、bfs建树,dfs赋值
*   先用bfs的方法把树创建出来,
*   然后dfs使用中序遍历树,同时赋值
*   时间复杂度:n
*   空间复杂度:应该是log(n),bfs过程中队列的缓存
* 4、好像还有一种更优的方法,但是太懒了,不想看。
*/
//1、暴力做法
class Solution {
public:
  TreeNode* dfs(const vector<int>& s, int l, int r) {
    if (l > r) return nullptr;
    int mid = l + r >> 1;
    return new TreeNode(s[mid], dfs(s, l, mid - 1), dfs(s, mid + 1, r));
  }
  TreeNode* sortedListToBST(ListNode* head) {
    vector<int>s;
    while (head != nullptr) {
      s.emplace_back(head->val);
      head = head->next;
    }
    return dfs(s, 0, s.size() - 1);
  }
};
//2、快慢指针
class Solution {
public:
  TreeNode* sortedListToBST(ListNode* head) {
    if (head == nullptr) return nullptr;
    if (head->next == nullptr) return new TreeNode(head->val);
    auto p = head;
    auto q = p;
    ListNode* t = nullptr;
    while (q != nullptr) {
      q = q->next;
      if (q == nullptr) break;
      t = p;
      p = p->next;
      q = q->next;
    }
    t->next = nullptr;
    return new TreeNode(p->val, sortedListToBST(head), sortedListToBST(p->next));
  }
};
//3、bfs+dfs
class Solution {
public:
  ListNode* dfs(TreeNode* node, ListNode* head) {
    if (node == nullptr) return head;
    head=dfs(node->left, head);
    node->val = head->val;
    head = head->next;
    head = dfs(node->right, head);
    return head;
  }
  TreeNode* sortedListToBST(ListNode* head) {
    if (head == nullptr) return nullptr;
    queue<TreeNode*>que;
    auto ansnode = new TreeNode;
    que.push(ansnode);
    auto p = head->next;
    while (p != nullptr) {
      que.front()->left = new TreeNode;
      que.push(que.front()->left);
      p = p->next;
      if (p != nullptr) {
        que.front()->right = new TreeNode;
        que.push(que.front()->right);
        p = p->next;
        que.pop();
      }
    }
    dfs(ansnode, head);
    return ansnode;
  }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值