左神算法进阶班5_1求二叉树中最大搜索子树大小

【题目】

给定一棵二叉树的头节点head,请返回最大搜索二叉子树的大小

【题解】

简化问题,想到该问题的解答应该有几种情形

第一种可能:

最大搜索二叉子树在head的左子树

第二种可能:

最大搜索二叉子树在head的右子树

第三种可能:

最大搜索二叉子树为自己;利用左子树的最大值与右子树的最小值

递归左子树,再递归右子树

信息1:左子树中最大搜索二叉树的大小

信息2:右子树中最大搜索二叉树的大小

信息3:左子树最大搜索二叉树的头结点

信息4:右子树最大搜索二叉树的头结点

信息5:左子树上的最大值

信息6:右子树上的最小值

使用递归,求每一个结点所包含的最大搜索二叉树

【代码】

  

  1 #pragma once
  2 #include <iostream>
  3 #include <vector>
  4 #include <algorithm>
  5
  6 using namespace std;
  7
  8 struct Node
  9 {
 10     int val;
 11     Node* l;
 12     Node* r;
 13     Node(int a) :val(a), l(nullptr), r(nullptr) {}
 14 };
 15
 16 //递归方式一
 17 struct returnType
 18 {
 19     int size;
 20     Node* head;
 21     int min;
 22     int max;
 23     returnType(int s, Node* h, int mi, int ma) :size(s), head(h), min(mi), max(ma) {}
 24 };
 25
 26 returnType* findSTree1(Node* head)
 27 {
 28     if (head == nullptr)
 29         return new returnType(0, nullptr, INT_MAX, INT_MIN);
 30     returnType* lInfo = findSTree1(head->l);//得到左子树的最大搜索二叉树
 31     returnType* rInfo = findSTree1(head->r);//得到右子树的最大搜索二叉树
 32
 33     int selfSize = 0;//判断包含该头节点的整棵树是否为搜索二次树
 34     if (lInfo->head == head->l &&
 35         rInfo->head == head->r &&
 36         lInfo->max < head->val &&
 37         rInfo->min > head->val
 38         )
 39         selfSize = lInfo->size + 1 + rInfo->size;
 40
 41     int maxSize = max(max(lInfo->size, rInfo->size), selfSize);//求得最大的搜索二叉树的大小
 42     Node* maxHead = nullptr;//选择最大的子树的头结点
 43     if (maxSize == selfSize)
 44         maxHead = head;
 45     else if (maxSize == lInfo->size)
 46         maxHead = lInfo->head;
 47     else
 48         maxHead = rInfo->head;
 49
 50     //这时返回的是包含head的整颗子树
 51     return new returnType(maxSize, maxHead,
 52         min(min(lInfo->min, rInfo->min), head->val),
 53         max(max(lInfo->max, rInfo->max), head->val));
 54 }
 55
 56
 57 //使用第二种递归
 58
 59 Node* findSTree2(Node* head, vector<int>&info)
 60 {
 61     if (head == nullptr)
 62     {
 63         info[0] = 0;
 64         info[1] = INT_MIN;
 65         info[2] = INT_MAX;
 66         return nullptr;
 67     }
 68     vector<int>hv = info;
 69     //得到左右子树的信息
 70     Node* lNode = findSTree2(head->l, info);
 71     vector<int>lv = info;
 72     Node* rNode = findSTree2(head->r, info);
 73     vector<int>rv = info;
 74     //更新信息
 75     info[1] = max(max(lv[1], rv[1]), head->val);
 76     info[2] = min(min(lv[2], rv[2]), head->val);
 77     //判断
 78     if (lNode == head->l && rNode == head->r && lv[1] < head->val && rv[2] > head->val)
 79     {
 80         info[0] = lv[0] + rv[0] + 1;
 81         return head;
 82     }
 83     info[0] = max(lv[0], rv[0]);
 84     return lv[0] > rv[0] ? lNode : rNode;
 85 }
 86
 87
 88 int maxSTree(Node* head)
 89 {
 90     vector<int>info(3,0);//储存字数的大小、最大值、最小值
 91     findSTree2(head, info);
 92     return info[0];
 93 }
 94
 95
 96
 97
 98 void Test()
 99 {
100     Node* root = new Node(9);
101     root->l = new Node(8);
102     root->r = new Node(1);
103     root->l->l = new Node(5);
104     root->l->r = new Node(9);
105     root->l->l->l = new Node(4);
106     root->l->l->r = new Node(6);
107     root->r->l = new Node(5);
108     root->r->r = new Node(3);
109     returnType* p = findSTree1(root);
110     cout << p->size << endl;
111
112     root = nullptr;
113     root = new Node(5);
114     root->l = new Node(2);
115     root->r = new Node(6);
116     root->l->l = new Node(1);
117     root->l->r = new Node(3);
118     p = findSTree1(root);
119     cout << p->size << endl;
120
121     root = nullptr;
122     root = new Node(9);
123     root->l = new Node(8);
124     root->r = new Node(1);
125     root->l->l = new Node(5);
126     root->l->r = new Node(9);
127     root->l->l->l = new Node(4);
128     root->l->l->r = new Node(6);
129     root->r->l = new Node(5);
130     root->r->r = new Node(3);
131     cout << maxSTree(root) << endl;
132
133     root = nullptr;
134     root = new Node(5);
135     root->l = new Node(2);
136     root->r = new Node(6);
137     root->l->l = new Node(1);
138     root->l->r = new Node(3);
139     cout << maxSTree(root) << endl;
140
141
142
143 }

原文地址:https://www.cnblogs.com/zzw1024/p/11072909.html

时间: 2024-07-31 22:32:30

左神算法进阶班5_1求二叉树中最大搜索子树大小的相关文章

左神算法进阶班5_3求公司的最大活跃度

[题目] 一个公司的上下节关系是一棵多叉树,这个公司要举办晚会,你作为组织者已经摸清了大家的心理: 一个员工的直接上级如果到场,这个员工肯定不会来. 每个员工都有一个活跃度的值,决定谁来你会给这个员工发邀请函,怎么让舞会的气氛最活跃? 返回最大的活跃值. 举例: 给定一个矩阵来表述这种关系 matrix = { 1,6 1,5 1,4 } 这个矩阵的含义是: matrix[0] = { 1 , 6 },表示0这个员工的直接上级为1, 0这个员工自己的活跃度为6 matrix[1] = { 1 ,

左神算法进阶班1_5BFPRT算法

在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BFPRT,则拿到整体的中位数num5)以num来划分整体数组,小于在左,大于在右边,使用[荷兰国旗方法]6)然后根据左右数组的规模,来确定进一步选择左右哪一部分:7)然后选择好后,继续 一:背景介绍在一大堆数中求其前k大或前k小的问题,简称TOP - K问题.而目前解决TOP - K问题最有效的算法即

左神算法进阶班3_1构造数组的MaxTree

题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一个没有重复元素的数组arr,写出生成这个数组的MaxTree的函数,要求如果数组长度为N,则时间负责度为O(N).额外空间负责度为O(N). 实现思路 将数组按照大根堆进行排序 然后直接按照大根堆进行构造一颗二叉树即可. 使用单调栈 通过使用单调栈,将数组中中所有数的左右比他大的数记录下来 当某个数

左神算法进阶班1_1添加最少字符得到原字符N次

Problem: 给定一个字符串str1,只能往str1的后面添加字符变成str2. 要求1:str2必须包含两个str1,两个str1可以有重合,但是不能以同一个位置开头. 要求2:str2尽量短最终返回str2 举例: str1 = 123,str2 = 123123 时,包含两个str1,且不以相同位置开头,且str2最短. str1 = 123123,str2 = 123123123 时,包含两个str1,且不以相同位置开头,且str2最短. str1 = 111,str2 = 1111

左神算法进阶班6_1LFU缓存实现

[题目] LFU也是一个著名的缓存算法,自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) [题解] LFU算法与LRU算法很像 但LRU是最新使用的排在使用频率最前面,也就是LRU是通过使用时间进行排序, 使用时间越新,其使用频率越高,而使用时间越久,其使用频率越低,即当空间满时,被删除的概率最大 而LFU是根据使用次数来算使用频率的,使用次数越多,其使用频率越高,使用次数越少,使用频率越低,当空间满时越容易被删除 同样,使用hash_map表和双向链表进行存

左神算法基础班3_13深度拷贝含有随机指针的链表

Problem: 复制含有随机指针节点的链表 [题目] 一种特殊的链表节点类描述如下: public class Node { public int value; public Node next; public Node rand; public Node(int data) { this.value = data; } } Node类中的value是节点值,next指针和正常单链表中next指针的意义 一 样,都指向下一个节点,rand指针是Node类中新增的指针,这个指 针可 能指向链表中

【编程题目】求二叉树中节点的最大距离

第 11 题(树)求二叉树中节点的最大距离...如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数.写一个程序,求一棵二叉树中相距最远的两个节点之间的距离. 思路:二叉树结构中只设了左右子节点的指针. 设单个结点的深度为0. 用后序遍历,得到每个结点为根的子树的最大深度.maxdistance记录该结点(左子树深度+右子树深度 + 2)是否超过已有的最远距离,若超过更新. 关键:空指针的深度设为-1,这样避免了复杂的分类讨论. 树每个结

编程之美之求二叉树中节点的最大距离

题目:如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数.写一个程序求一棵二叉树中相距最远的两个节点之间的距离. 分析:树上分析的很清楚,计算一个二叉树的最大距离有两个情况: 1. 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点. 2. 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者. 但是树上的代码使用了额外的节点字段,这里给出我的代码,思路是一样的: struct BinaryTree { int valu

编程之美3.8 求二叉树中节点的最大距离

描述:如果把二叉树看成一个图,父子节点之间的连线看成双向的,定义“距离”为两个节点之间边的个数.求二叉树中相距最远的两个节点的距离. 思路:相距最远的两个节点一定是叶子节点,且这两个叶子节点的路径有两种情况: 1. 该路径经过root节点,则两个叶子节点分属root.left和root.right为根的子树,而且是两个子树中距离root.left和root.right最远的叶子节点: 2. 该路径不经过root节点,则这两个叶子节点的root.left或root.right上: 根据以上分析,参