LeetCode 108.109. 将有序数组|链表转换为二叉搜索树 | C++语言版

LeetCode 108. 将有序数组转换为二叉搜索树

题目描述

题目地址108. 将有序数组转换为二叉搜索树
在这里插入图片描述
在这里插入图片描述

解题思路

思路一:使用递归
代码实现

C++

/**
 * 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 {
public:
    TreeNode* traversal(vector<int>& nums,int left,int right){
        if(left>right) return NULL;
        int mid=left+((right-left)/2);

        TreeNode* root=new TreeNode(nums[mid]);
        //定义的区间为左闭右闭[left,mid-1]
        root->left=traversal(nums,left,mid-1);
        //定义的区间为左闭右闭[mid+1,right]
        root->right=traversal(nums,mid+1,right);

        return root;
    }

    TreeNode* sortedArrayToBST(vector<int>& nums) {
        //一个整数数组 nums(升序) 排列,将其转换为一棵高度平衡二叉搜索树(每个节点的左右两个子树的高度差的绝对值不超过1)

        //寻找数组中间位置的节点作为分割点,分割点作为当前节点,然后递归左区间和右区间
        //如果数组长度为偶数,中间节点有两个,取哪一个都可以,只不过构成了不同的平衡二叉搜索树

        //定义的区间为左闭右闭[0,nums.size()-1]
        TreeNode* root=traversal(nums,0,nums.size()-1);
        return root;

    }
};
运行结果

在这里插入图片描述

参考文章:

https://programmercarl.com/0108.%E5%B0%86%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html#%E9%80%92%E5%BD%92

思路二:减少遍历节点数
代码实现

C++

在这里插入代码片
运行结果
参考文章:

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

题目描述

题目地址109. 有序链表转换二叉搜索树
给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 1。
在这里插入图片描述

解题思路

思路一:使用分治,快慢双指针
代码实现

C++

/**
 * 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 {
public:
    ListNode* getMid(ListNode* left,ListNode* right){
        //使用快慢指针找链表的中间节点
        //快慢指针同时从left(head)头结点出发
        ListNode* fast=left;
        ListNode* slow=left;

        //快指针每次走两步,慢指针每次走一步
        while(fast!=right && fast->next!=right){
            fast=fast->next;
            fast=fast->next;
            slow=slow->next;
        }
        //当快指针fast到达链表末尾节点时,慢指针slow正好到达链表的中间节点
        return slow;
    }

    TreeNode* traversal(ListNode* left,ListNode* right){
        if(left==right) return NULL;
        ListNode* mid=getMid(left,right);

        //将中间节点作为二叉树的根节点
        TreeNode* root=new TreeNode(mid->val);
        //定义的区间为左闭右闭[left,mid]
        root->left=traversal(left,mid);
        //定义的区间为左闭右闭[mid->next,right]
        root->right=traversal(mid->next,right);

        return root;
    }

    TreeNode* sortedListToBST(ListNode* head) {
        //一个单链表,其中的元素按升序排列,将其转换为一棵高度平衡二叉搜索树(每个节点的左右两个子树的高度差的绝对值不超过1)

        //寻找链表中间位置的节点作为分割点(使用快慢指针法),分割点作为当前节点,然后递归左区间和右区间
        //如果链表长度为偶数,中间节点有两个,取哪一个都可以,只不过构成了不同的平衡二叉搜索树

        //head:链表的头结点 nullptr:链表的末尾结点
        TreeNode* root=traversal(head,nullptr);
        return root;
    }
};
运行结果

在这里插入图片描述

参考文章:

https://leetcode.cn/problems/convert-sorted-list-to-binary-search-tree/solutions/378582/you-xu-lian-biao-zhuan-huan-er-cha-sou-suo-shu-1-3/?orderBy=most_votes

思路二:减少遍历节点数
代码实现

C++

在这里插入代码片
运行结果
参考文章:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李莲花*

多谢多谢,来自一名大学生的感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值