链接:109. 有序链表转换二叉搜索树

题解:https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/solution/shou-hua-tu-jie-san-chong-jie-fa-jie-zhu-shu-zu-ku/

方法1:将有序链表转成有序数组
先将有序链表转成有序数组,我之前画过下图,想象成一条绳,提起中点作为根节点,分出左右两部分,再提起各自的中点作为根节点……不断分治,这根绳就成了 BST 的模样。

/***  * Definition for singly-linked list.*   * struct ListNode {*    *     int val;*     *     ListNode *next;*      *     ListNode(int x) : val(x), next(NULL) {}*       * };*        */
/***  * Definition for a binary tree node.*   * struct TreeNode {*    *     int val;*     *     TreeNode *left;*      *     TreeNode *right;*       *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}*        * };*         */
class Solution {
public:void list_to_vec(ListNode* head, vector<ListNode*>* vec) {for(auto ite = head; ite != nullptr; ite = ite->next) {vec->push_back(ite);}}TreeNode* sortedListToBST(ListNode* head) {vector<ListNode*> vec;list_to_vec(head, &vec);return dfs(vec, 0, vec.size()-1);}TreeNode* dfs(const vector<ListNode*>& vec, int begin, int end) {if(begin > end) {return nullptr;}int mid = (begin + end)/2;TreeNode* root = new TreeNode(vec[mid]->val);root->left = dfs(vec, begin, mid-1);root->right = dfs(vec, mid+1, end);return root;}
};

方法2:快慢指针
找到链表的中间点,有个小技巧:快、慢指针指向头结点,快指针一次走两步,慢指针一次走一步,当快指针走到尾节点时,慢指针正好走到链表的中间。然后断开成两个链表,分而治之。

为了断开,我们需要一个指针记录慢指针的前一个节点,因为单向链表的节点没有前驱指针。

const sortedListToBST = (head) => {if (head == null) return null;let slow = head;let fast = head;let preSlow; // 保存slow的前一个节点while (fast && fast.next) {preSlow = slow;slow = slow.next;fast = fast.next.next;}const root = new TreeNode(slow.val);if (preSlow != null) { // 中点slow不是head,需要构建左子树preSlow.next = null; // 切断preSlow和中点slowroot.left = sortedListToBST(head); }root.right = sortedListToBST(slow.next);return root;
};

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
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 ) / 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);}
};

109. 有序链表转换二叉搜索树相关推荐

  1. ( “树” 之 BST) 109. 有序链表转换二叉搜索树 ——【Leetcode每日一题】

    二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点. 二叉查找树中序遍历有序. 109. 有序链表转换二叉搜索树 给定一个单链表的头节点 head ,其中的元素 按升序排序 , ...

  2. 【LeetCode每日一题】——109.有序链表转换二叉搜索树

    文章目录 一[题目类别] 二[题目难度] 三[题目编号] 四[题目描述] 五[题目示例] 六[题目提示] 七[解题思路] 八[时间频度] 九[代码实现] 十[提交结果] 一[题目类别] 二叉树 二[题 ...

  3. Java实现 LeetCode 109 有序链表转换二叉搜索树

    109. 有序链表转换二叉搜索树 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. ...

  4. LeetCode 109. 有序链表转换二叉搜索树(快慢指针+递归)

    1. 题目 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 来源:力扣(LeetC ...

  5. Leetcode 109.有序链表转换二叉搜索树

    Time: 20190901 Type: Meidum 题目描述 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子 ...

  6. Leetcode 109. 有序链表转换二叉搜索树 解题思路及C++实现

    方法一:将链表转为数组来处理 解题思路: 因为链表不好处理,所以我先把链表处理成数组,因为是一个升序数组,所以直接将中间的数当成根结点,然后对左半部分的节点和右半部分的节点进行递归构建二叉搜索树. 在 ...

  7. LeetCode 109. 有序链表转换二叉搜索树

    思路: 快慢指针找到中间节点,中间节点为根节点, 将链表分为左右两部分(注意前半部分节点next置null),左部分为左子树,右部分为右子树 递归实现左右子树,返回根节点 public static ...

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

    109. 有序链表转换二叉搜索树 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. ...

  9. 【算法】有序链表转换二叉搜索树和从中序与后序遍历序列构造二叉树Java解答参考

    三道算法题 1.有序链表转换二叉搜索树 Java代码参考 2.从中序与后序遍历序列构造二叉树 Java代码参考 3.移除元素 Java代码参考 1.有序链表转换二叉搜索树 给定一个单链表,其中的元素按 ...

最新文章

  1. Python 多线程抓取网页 牛人 use raw socket implement http request great
  2. larvare数据库引入php_PHP全栈学习笔记6
  3. [攻防世界 pwn]——hello_pwn
  4. ASP.NET Core2基于RabbitMQ对Web前端实现推送功能
  5. java开发工程师工作内容怎么写
  6. jstl与EL表达式处理字符串
  7. 百度知道回答html代码,html - JavaScript面试题:页面编码和被请求的资源编码 ,如果不一致,如何处理?百度上搜到一个答案,不知道是否正确?...
  8. Python垃圾回收(gc)拖累了程序执行性能?
  9. 基于FFmpeg的Qt视频播放器
  10. PPT太大如何压缩到最小?
  11. 浅谈网络安全产品的分类
  12. 华为认证hcia含金量_华为认证那个证书有什么用?
  13. Matlab图像的平移,旋转,缩放,裁剪
  14. Web网页制作——花店网站(彼岸の花 偏安一隅)
  15. mysql查询表可编辑器_数据库查看编辑工具(Exportizer)
  16. [BZOJ1116] CLO
  17. 只有过来的人才知道其中的辛酸,在别人看来只能看到表面的光鲜亮丽
  18. ubuntu18.04重装R
  19. 主机开启双网卡不能上网的一个解决办法
  20. usb摄像头设备名重复的问题

热门文章

  1. 数据结构_二叉树非递归遍历
  2. 开源与安全兼备 IBM LinuxONE轻松掌控关键业务
  3. ettercap dns_spoof
  4. 不要进行过度设计,某一层存在真的有意义吗?是否可以更简单。
  5. DateTime和DateTime2
  6. 职场80后新人修炼五诀
  7. C++ 类的设计与实现规范
  8. MBIST:用于嵌入式存储器的可测试设计技术
  9. hybrid App cordova打包webapp PhoneGap
  10. 深入了解preventDefault与stopPropagation