IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> LeetCode[104/108/109]二叉树的最大深度、将有序数组转换为二叉搜索树、 将有序链表转换为二叉搜索树 C/C++——Week 2 II -> 正文阅读

[C++知识库]LeetCode[104/108/109]二叉树的最大深度、将有序数组转换为二叉搜索树、 将有序链表转换为二叉搜索树 C/C++——Week 2 II

104.二叉树的最大深度

题目描述[简单]:

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

示例1:
输入: [3,9,20,null,null,15,7]
输出:3

思路[递归]:

本题跟昨天的题思路都是一样的,都可以用递归来做。
首先要列出为空的情况,此时输出0;
当有结点之后,我们要比较左子树的深度值和右子树的深度值,看哪个最大。这里有个点需要注意:我们要算上最上头的那个根节点root。所以return的时候要+1
看左子树和右子树的深度,就是看左子树的子树深度,这就是递归的思想。

终止递归条件:树遍历到底部,子树为空。

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:
    int maxDepth(TreeNode* root) {
        if(root == NULL)
        return 0;
       return max(maxDepth(root->left),maxDepth(root->right)) + 1;

    }
    
};

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

题目描述[简单]:

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]/[0,-10,5,null,-3,null,9]
1 ———————— 2

思路[递归]:

本题依旧是递归的思想。
本题的题目是给出了一个有序数组,然后再来创建BST。众所周知,BST的中序遍历就是数组的升序排列,因此本题可以变成:
通过BST的中序序列来推断这棵BST树的层序遍历序列

我们可以在升序序列中的任取一个元素作为根节点,将该元素左边元素进行升序排列从而构建左子树,将该元素右边元素进行升序排列从而构建右子树。又因为是高度平衡的树,所以我们选择升序序列的中间元素作为根节点。

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* sortedArrayToBST(vector<int>& nums) {
        return sortedArray(nums , 0 , nums.size()-1);
    }
     TreeNode* sortedArray(vector<int>& nums , int l , int r){
         if(r<l)//如果数组为空
         return nullptr;//直接返回空结点 
         int mid = l + (r-l) / 2;// 以升序数组的中间元素作为根节点 root
         TreeNode* root = new TreeNode(nums[mid]);//把中间节点作为根节点
         root->left = sortedArray(nums, l, mid - 1);// 通过递归的方式来构建 root 的左子树
         root->right = sortedArray(nums, mid + 1, r);//通过递归的方式来构建 root 的右子树
         return root;
     }
};

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

题目描述[中等]:

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

示例 1:
输入: head = [-10,-3,0,5,9]
输出: [0,-3,9,-10,null,5]
解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。

3

思路[递归+双指针]:

这种题第一次看见就觉得不知道如何下手,感觉可以用递归写,但是不知道怎么找中间结点,就是怎么把他们联系起来,然后我看题解说可以用双指针——快慢指针。快指针一次走两步,慢指针一次走一步。
那么链表的中间结点方法:
快慢指针最初都指向头结点,分别一次走两步和一步,当快指针走到尾节点时,慢指针正好走到链表的中间。此时断成两个链表,将其分开。
实现链表断开的方法:
建立一个空指针用来保存慢指针的前一个节点,从而实现断开操作。而保存前一个而不是当前那个的原因是:单向链表的结点没有前驱指针。

思路

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:
    TreeNode* sortedListToBST(ListNode* head) {
         if(head==nullptr)
            return nullptr;
       if(head->next == nullptr) //如果只有一个节点
       return new TreeNode(head->val);      //直接创建,然后返回

       ListNode* mid = getMid(head);//调用中间值方法
       
       //构造二叉树
       TreeNode* root = new TreeNode(mid->val);//此时根节点就是中间节点
       root->left = sortedListToBST(head);//递归构造左子树,由于链表在中间节点前断开,所以直接传入头结点
       root->right = sortedListToBST(mid->next);//递归构造右子树,此时传入中间节点的下一个节点
       
       return root;

    }
   ListNode* getMid(ListNode* head){//获取链表中间节点的方法,在获得中间值同时还要把链表在中间值前断开(方便递归操作)
        ListNode* node = nullptr;//定义一个空指针
        ListNode* fast = head;//利用双指针来找中间节点,此时定义两个指针,快指针和慢指针
        ListNode* slow = head;
        while(fast && fast->next){
            fast = fast->next->next;//快指针一次移动两步
            node = slow;//更新node指针
            slow = slow->next;//慢指针一次移动一步
        }
        if(node!=nullptr)//移动结束后,node非空,就在此断开链表
        node->next = nullptr;
        return slow;
        }
       
    
};

时间复杂度:O(nlogn);

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:25:04  更:2022-08-06 10:25:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:07:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码