当前位置: 首页 > news >正文

Day72:10.15:leetcode 二叉树20道题,用时3h30min

1. 104. 二叉树的最大深度(简单)

104. 二叉树的最大深度 - 力扣(LeetCode)

思想

1.给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

代码
class Solution {
public:int maxDepth(TreeNode* root) {if (root == nullptr)return 0;return max(maxDepth(root->left), maxDepth(root->right)) + 1;}
};
2. 111. 二叉树的最小深度(简单)

111. 二叉树的最小深度 - 力扣(LeetCode)

思想

1.给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

代码
class Solution {
public:int minDepth(TreeNode* root) {if (root == nullptr)return 0;if (root->left == nullptr)return minDepth(root->right) + 1;if (root->right == nullptr)return minDepth(root->left) + 1;return min(minDepth(root->left), minDepth(root->right)) + 1;}
};
3. 965. 单值二叉树(简单)

965. 单值二叉树 - 力扣(LeetCode)

思想

1.如果二叉树每个节点都具有相同的值,那么该二叉树就是_单值_二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false

代码

自顶向下(先判断自己,再判断左右子树)

class Solution {
public:bool isUnivalTree(TreeNode* root) {if (root == nullptr)return true;if (root->left != nullptr && root->val!=root->left->val)return false;if (root->right != nullptr && root->val!=root->right->val)return false;return isUnivalTree(root->left) && isUnivalTree(root->right); }
};
4. 100. 相同的树(简单)

100. 相同的树 - 力扣(LeetCode)

思想

1.给你两棵二叉树的根节点 pq ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

代码
class Solution {
public:bool isSameTree(TreeNode* p, TreeNode* q) {if (p == nullptr || q == nullptr) // 指针比较return p == q;if (p->val != q->val) // 值比较return false;return isSameTree(p->left, q->left) &&isSameTree(p->right, q->right); // 子树比较}
};
5. 101. 对称二叉树(简单,学习递归写法)

101. 对称二叉树 - 力扣(LeetCode)

思想

1.给你一个二叉树的根节点 root , 检查它是否轴对称。
2.在[[十五.二叉树#4. 100. 相同的树(简单)]]的基础上改写,判断轴对称就是左右两个树p,q,p和q的值是否相等,相等的话p的左子树是否等于q的右子树,p的右子树是否等于q的左子树

代码

搜索比较

class Solution {
public:void dfs2(TreeNode* cur, vector<int>& res) {if (cur == nullptr) {res.push_back(500);return;}res.push_back(cur->val);dfs2(cur->right, res);dfs2(cur->left, res);}void dfs1(TreeNode* cur, vector<int>& res) {if (cur == nullptr) {res.push_back(500);return;}res.push_back(cur->val);dfs1(cur->left, res);dfs1(cur->right, res);}bool isSymmetric(TreeNode* root) {if (root == nullptr)return true;if (root->left == nullptr || root->right == nullptr)return root->left == root->right;vector<int> resL, resR;dfs1(root->left, resL);dfs2(root->right, resR);return resL == resR;}
};

递归版本:

class Solution {
public:bool isSameTree(TreeNode* p, TreeNode* q) {if (p == nullptr || q == nullptr)return p == q;if (p->val != q->val)return false;return isSameTree(p->left, q->right) && isSameTree(p->right, q->left);}bool isSymmetric(TreeNode* root) {return isSameTree(root->left, root->right);}
};
6. 951. 翻转等价二叉树(中等)

951. 翻转等价二叉树 - 力扣(LeetCode)

思想

1.我们可以为二叉树 T 定义一个 翻转操作 ,如下所示:选择任意节点,然后交换它的左子树和右子树。
只要经过一定次数的翻转操作后,能使 X 等于 Y,我们就称二叉树 X 翻转 等价 于二叉树 Y
这些树由根节点 root1root2 给出。如果两个二叉树是否是_翻转 等价_ 的树,则返回 true ,否则返回 false
2.跟[[十五.二叉树#4. 100. 相同的树(简单)]]一样,只不过多了可以左子树等于右子树且右子树等于左子树

代码
class Solution {
public:bool flipEquiv(TreeNode* root1, TreeNode* root2) {if (root1 == nullptr || root2 == nullptr)return root1 == root2;if (root1->val != root2->val)return false;return (flipEquiv(root1->left, root2->left) &&flipEquiv(root1->right, root2->right) ) || (flipEquiv(root1->left, root2->right) &&flipEquiv(root1->right, root2->left) );}
};
7. 1379. 找出克隆二叉树中的相同节点(简单)

1379. 找出克隆二叉树中的相同节点 - 力扣(LeetCode)

思想

1.给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target
其中,克隆树 cloned 是原始树 original 的一个 副本
请找出在树 cloned 中,与 target 相同 的节点,并返回对该节点的引用(在 C/C++ 等有指针的语言中返回 节点指针,其他语言返回节点本身)。
**注意:**你 不能 对两棵二叉树,以及 target 节点进行更改。只能 返回对克隆树 cloned 中已有的节点的引用。

代码
class Solution {
public:TreeNode* getTargetCopy(TreeNode* original, TreeNode* cloned,TreeNode* target) {if (original == NULL)return NULL;if (original == target)return cloned;TreeNode* tmp = getTargetCopy(original->left, cloned->left, target);if (tmp != NULL)return tmp;return getTargetCopy(original->right, cloned->right, target);}
};
8. 110. 平衡二叉树(简单,学习优化)

110. 平衡二叉树 - 力扣(LeetCode)

思想

1.给定一个二叉树,判断它是否是 平衡二叉树
2.我的代码每次判断就要获取一个高度,会重复计算
3.而优化代码是在[[十五.二叉树#1. 104. 二叉树的最大深度(简单)]]的基础上改的,不满足条件的高度为-1,不断向上归

代码
class Solution {
public:int getDepth(TreeNode* cur) {if (cur == nullptr)return 0;return max(getDepth(cur->left), getDepth(cur->right)) + 1;}bool isBalanced(TreeNode* root) {if (root == nullptr)return true;int lDep = getDepth(root->left), rDep = getDepth(root->right);if (abs(lDep - rDep) > 1)return false;return isBalanced(root->left) && isBalanced(root->right);}
};

优化代码:

class Solution {
public:int getDepth(TreeNode* cur) {if (cur == nullptr)return 0;int lDep = getDepth(cur->left);if (lDep == -1)return -1;int rDep = getDepth(cur->right);if (rDep == -1 || abs(lDep - rDep) > 1)return -1;return max(lDep, rDep) + 1;}bool isBalanced(TreeNode* root) { return getDepth(root) != -1; }
};
9. 226.翻转二叉树(简单)

226. 翻转二叉树 - 力扣(LeetCode)

思想

1.给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
2.有返回值的函数调用时可以不将返回值赋值,直接舍弃

代码

自顶向下:

class Solution {
public:TreeNode* invertTree(TreeNode* root) {if (root == nullptr) {return nullptr;}swap(root->left, root->right); invertTree(root->left); invertTree(root->right); return root;}
};

自底向上(必须接收返回值,因为底的指针已经变了):

class Solution {
public:TreeNode* invertTree(TreeNode* root) {if (root == nullptr) {return nullptr;}auto newL = invertTree(root->left);auto newR = invertTree(root->right);root->left = newR;root->right = newL;return root;}
};
10. 617.合并二叉树(简单,学习递归返回值的利用)

617. 合并二叉树 - 力扣(LeetCode)

思想

1.给你两棵二叉树: root1root2
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
2.此题帮助理解在归的过程中更新当前值

root1->left=mergeTrees(root1->left,root2->left);
root1->right=mergeTrees(root1->right,root2->right);
代码
class Solution {
public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if(root2==nullptr){return root1;}if(root1==nullptr){return root2;}root1->val+=root2->val;root1->left=mergeTrees(root1->left,root2->left);root1->right=mergeTrees(root1->right,root2->right);return root1;}
};
11. 2331. 计算布尔二叉树的值(简单)

2331. 计算布尔二叉树的值 - 力扣(LeetCode)

思想

1.给你一棵 完整二叉树 的根,这棵树有以下特征:

  • 叶子节点 要么值为 0 要么值为 1 ,其中 0 表示 False1 表示 True
  • 非叶子节点 要么值为 2 要么值为 3 ,其中 2 表示逻辑或 OR3 表示逻辑与 AND
    计算 一个节点的值方式如下:
  • 如果节点是个叶子节点,那么节点的 为它本身,即 True 或者 False
  • 否则,计算 两个孩子的节点值,然后将该节点的运算符对两个孩子值进行 运算
    返回根节点 root 的布尔运算值。
    完整二叉树 是每个节点有 0 个或者 2 个孩子的二叉树。
    叶子节点 是没有孩子的节点。
    2.逻辑或和与是||,&&,按位或和与是|,&
代码
class Solution {
public:bool evaluateTree(TreeNode* root) {if (root->left == nullptr && root->right == nullptr)return root->val;int lVal = evaluateTree(root->left), rVal = evaluateTree(root->right);if (root->val == 2)return lVal || rVal;return lVal && rVal;}
};
12. 508. 出现次数最多的子树元素和(中等)

508. 出现次数最多的子树元素和 - 力扣(LeetCode)

思想

1.给你一个二叉树的根结点 root ,请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。
一个结点的 「子树元素和」 定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。
2.再维护个最大次数变量,可以简化后面逻辑

代码
class Solution {
public:typedef pair<int, int> PII;map<int, int> sumToCnt;int getSum(TreeNode* cur) {if (cur == nullptr)return 0;int lSum = getSum(cur->left), rSum = getSum(cur->right);int tSum = cur->val + lSum + rSum;++sumToCnt[tSum];return tSum;}vector<int> findFrequentTreeSum(TreeNode* root) {getSum(root);vector<int> res;vector<PII> tmp;for (auto& t : sumToCnt)tmp.push_back({t.second, t.first});sort(tmp.begin(), tmp.end(), greater<>());int maxCnt = tmp[0].first;res.push_back(tmp[0].second);for (int i = 1; i < tmp.size(); ++i) {if (tmp[i].first < maxCnt)break;res.push_back(tmp[i].second);}return res;}
};

优化代码:

class Solution {
public:typedef pair<int, int> PII;map<int, int> sumToCnt;int maxCnt = 0;int getSum(TreeNode* cur) {if (cur == nullptr)return 0;int lSum = getSum(cur->left), rSum = getSum(cur->right);int tSum = cur->val + lSum + rSum;++sumToCnt[tSum];maxCnt = max(maxCnt, sumToCnt[tSum]); return tSum;}vector<int> findFrequentTreeSum(TreeNode* root) {getSum(root);vector<int> res;vector<PII> tmp;for (auto& t : sumToCnt) {if (t.second == maxCnt)res.push_back(t.first);}return res;}
};
13. 563. 二叉树的坡度(简单)

563. 二叉树的坡度 - 力扣(LeetCode)

思想

1.给你一个二叉树的根节点 root ,计算并返回 整个树 的坡度 。
一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。
整个树 的坡度就是其所有节点的坡度之和。

代码
class Solution {
public:int res = 0;int getSum(TreeNode* root) {if (root == nullptr)return 0;int lSum = getSum(root->left), rSum = getSum(root->right);res += abs(lSum - rSum);return lSum + rSum + root->val;}int findTilt(TreeNode* root) {getSum(root);return res;}
};
14. 606.根据二叉树创建字符串(中等)

606. 根据二叉树创建字符串 - 力扣(LeetCode)

思想

1.给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。
空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
2.递归逻辑:根(左)(右),右不空,必有(左),右空,根据左是否空来决定有无()

代码
class Solution {
public:string tree2str(TreeNode* root) {if (root == nullptr)return "";string lStr = tree2str(root->left), rStr = tree2str(root->right);string res = to_string(root->val);if (rStr == "") {if (lStr != "")res += "(" + lStr + ")";} else {res += "(" + lStr + ")" + "(" + rStr + ")";}return res;}
};
15. 2265. 统计值等于子树平均值的节点数(中等)

2265. 统计值等于子树平均值的节点数 - 力扣(LeetCode)

思想

1.给你一棵二叉树的根节点 root ,找出并返回满足要求的节点数,要求节点的值等于其 子树 中值的 平均值
注意:

  • n 个元素的平均值可以由 n 个元素 求和 然后再除以 n ,并 向下舍入 到最近的整数。
  • root子树root 和它的所有后代组成。
代码
class Solution {
public:int res = 0;vector<int> getSumCnt(TreeNode* cur) {if (cur == nullptr)return {0, 0};vector<int> lSumCnt = getSumCnt(cur->left),rSumCnt = getSumCnt(cur->right);int tSum = lSumCnt[0] + rSumCnt[0] + cur->val;int tCnt = lSumCnt[1] + rSumCnt[1] + 1;if (tSum / tCnt == cur->val)++res;return {tSum, tCnt};}int averageOfSubtree(TreeNode* root) {getSumCnt(root);return res;}
};
16. 1026. 节点与其祖先之间的最大差值(中等)
思想

做过了,过

代码

17. 3319. 第K大的完美二叉子树的大小(中等)

3319. 第 K 大的完美二叉子树的大小 - 力扣(LeetCode)

思想

1.给你一棵 二叉树 的根节点 root 和一个整数k
返回第 k 大的 完美二叉子树**的大小,如果不存在则返回 -1
完美二叉树 是指所有叶子节点都在同一层级的树,且每个父节点恰有两个子节点。
2.因为"每个父节点恰有两个子节点",所以知道深度就知道大小,深度h,大小2^h-1,所以优先队列记录深度,最后计算大小

代码
class Solution {
public:priority_queue<int, vector<int>, greater<int>> pq;vector<int> getSumDep(TreeNode* cur, int& k) {if (cur == nullptr)return {0, 0};vector<int> lSumDep = getSumDep(cur->left, k),rSumDep = getSumDep(cur->right, k);int lDep = lSumDep[1], rDep = rSumDep[1];if (lDep == -1 || rDep == -1 || lDep != rDep)return {0, -1};int lSum = lSumDep[0], rSum = rSumDep[0];int tSum = lSum + rSum + 1;pq.push(tSum);if (pq.size() > k)pq.pop();return {tSum, lDep + 1};}int kthLargestPerfectSubtree(TreeNode* root, int k) {getSumDep(root, k);if (pq.size() < k)return -1;return pq.top();}
};

优化:

class Solution {
public:priority_queue<int, vector<int>, greater<int>> pq;int getDep(TreeNode* cur, int& k) {if (cur == nullptr)return 0;int lDep = getDep(cur->left, k), rDep = getDep(cur->right, k);if (lDep == -1 || rDep == -1 || lDep != rDep)return -1;pq.push(lDep + 1);if (pq.size() > k)pq.pop();return lDep + 1;}int kthLargestPerfectSubtree(TreeNode* root, int k) {getDep(root, k);if (pq.size() < k)return -1;return (1 << pq.top()) - 1;}
};
18. 1339. 分裂二叉树的最大乘积(中等,取模理解)

1339. 分裂二叉树的最大乘积 - 力扣(LeetCode)

思想

1.给你一棵二叉树,它的根为 root 。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。
由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回。
2.不能在max比较时对比较数先取模,否则会让这个数比另一比较数小

代码
class Solution {
public:typedef long long ll;const int mod=1e9+7;ll sum=0;ll res=0;void dfs(TreeNode* cur){if(cur==nullptr)    return;sum+=cur->val;dfs(cur->left);dfs(cur->right);}ll getSum(TreeNode* cur){if(cur==nullptr)    return 0;ll lSum=getSum(cur->left),rSum=getSum(cur->right);res=max(res,lSum*(sum-lSum));res=max(res,rSum*(sum-rSum));return lSum+rSum+cur->val;}int maxProduct(TreeNode* root) {dfs(root);getSum(root);return res%mod;}
};
19. 1372. 二叉树中的最长交错路径(中等)

1372. 二叉树中的最长交错路径 - 力扣(LeetCode)

思想

做过了,过

代码

20. 1145. 二叉树着色游戏(中等,学习)

1145. 二叉树着色游戏 - 力扣(LeetCode)

思想

1.有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中,给出二叉树的根节点 root,树上总共有 n 个节点,且 n 为奇数,其中每个节点上的值从 1 到 n 各不相同。
最开始时:

  • 「一号」玩家从 [1, n] 中取一个值 x1 <= x <= n);
  • 「二号」玩家也从 [1, n] 中取一个值 y1 <= y <= n)且 y != x
    「一号」玩家给值为 x 的节点染上红色,而「二号」玩家给值为 y 的节点染上蓝色。
    之后两位玩家轮流进行操作,「一号」玩家先手。每一回合,玩家选择一个被他染过色的节点,将所选节点一个 未着色 的邻节点(即左右子节点、或父节点)进行染色(「一号」玩家染红色,「二号」玩家染蓝色)。
    如果(且仅在此种情况下)当前玩家无法找到这样的节点来染色时,其回合就会被跳过。
    若两个玩家都没有可以染色的节点时,游戏结束。着色节点最多的那位玩家获得胜利 ✌️。
    现在,假设你是「二号」玩家,根据所给出的输入,假如存在一个 y 值可以确保你赢得这场游戏,则返回 true ;若无法获胜,就请返回 false 。
    2.想到用贪心思想,计算左子树,右子树,父节点子树
    ![[1145. 二叉树着色游戏.png]]
    左子树lSum,右子树rSum,父节点子树n-1-lSum-rSum,哪棵子树最大,二号玩家选哪棵,得到maxSum,让maxSum>n-maxSum
代码
class Solution {
public:int lSum = 0, rSum = 0;int getSum(TreeNode* cur, int x) {if (cur == nullptr)return 0;int tmpLSUm = getSum(cur->left, x), tmpRSUm = getSum(cur->right, x);if (cur->val == x) {lSum = tmpLSUm;rSum = tmpRSUm;}return tmpLSUm + tmpRSUm + 1;}bool btreeGameWinningMove(TreeNode* root, int n, int x) {getSum(root, x);int maxSum = max({lSum, rSum, n - 1 - lSum - rSum});// maxSum>n-maxSumreturn maxSum > n - maxSum;}
};
http://www.dtcms.com/a/488593.html

相关文章:

  • 企业网站推广方案设计网站页面链接怎么做的
  • 网站站内推广计划书门户网站建设管理
  • 做异形建筑的网站荆州房地产网站建设
  • 学校网站开发系统的背景wordpress米课
  • 着陆页制作网站简单网页制作素材
  • kfifo
  • 广州天河区网站建设怎么地wordpress
  • wordpress网站被拒登企业官网招聘
  • 【时时三省】(C语言基础)用格式化的方式读写文本文件
  • 国外 网站 模板广州建站哪个济南兴田德润实惠吗
  • 网站快速收录工具医疗器械类网站icp备案前置审批
  • 济南 网站推广制作公司网站设计要求
  • 曲靖网站微信建设百度指数分析数据
  • 遵义专业网站建设公司电话前端代码大全
  • 上海注册公司多久义乌网站建设优化排名
  • 网站上做百度广告赚钱么泰安人才网招聘网
  • 从零开始读懂Transformer:架构解析与PyTorch实现
  • 网站备案核验单酒店网站制作策划
  • 宁夏建设厅网站领导做平台网站要什么条件
  • 去别人网站挂黑链西地那非可以长期吃吗
  • 怎么做二维码微信扫后直到网站php做网站的源码
  • ASP 总结
  • 企业需求做网站在哪儿交易对网站开发语言的统计
  • 江西住房和城乡建设部网站首页东莞高森网络营销
  • 网站优化包括郑州seo优化顾问
  • C++ 重载运算符和重载函数
  • 杭州桐庐网站建设做两个网站 之间超链接
  • 怎样建设好门户网站宜春网站设计公司
  • 南通网站制作公司哪家好网站制作的相关术语有哪些
  • 做网站需要多少钱呢专业团队黑人