力扣OJ(1600+)

目录

1602. 找到二叉树中最近的右侧节点

1612. 检查两棵二叉表达式树是否等价

1634. 求两个多项式链表的和

1644. 二叉树的最近公共祖先 II

1650. 二叉树的最近公共祖先 III

1666. 改变二叉树的根节点

1676. 二叉树的最近公共祖先 IV


1602. 找到二叉树中最近的右侧节点

二叉树

1612. 检查两棵二叉表达式树是否等价

二叉表达式树是一种表达算术表达式的二叉树。二叉表达式树中的每一个节点都有零个或两个子节点。 叶节点(有 0 个子节点的节点)表示操作数,非叶节点(有 2 个子节点的节点)表示运算符。在本题中,我们只考虑 '+' 运算符(即加法)。

给定两棵二叉表达式树的根节点 root1 和 root2 。如果两棵二叉表达式树等价,返回 true ,否则返回 false 。

当两棵二叉搜索树中的变量取任意值,分别求得的值都相等时,我们称这两棵二叉表达式树是等价的。

示例 1:

输入: root1 = [x], root2 = [x]
输出: true
示例 2:

输入:root1 = [+,a,+,null,null,b,c], root2 = [+,+,a,b,c]
输出:true
解释:a + (b + c) == (b + c) + a
示例 3:

输入: root1 = [+,a,+,null,null,b,c], root2 = [+,+,a,b,d]
输出: false
解释: a + (b + c) != (b + d) + a
 

提示:

两棵树中的节点个数相等,且节点个数为范围 [1, 4999] 内的奇数。
Node.val 是 '+' 或小写英文字母。
给定的树保证是有效的二叉表达式树。
 

进阶:当你的答案需同时支持 '-' 运算符(减法)时,你该如何修改你的答案

template<typename T>
vector<T> vecAdd(const vector<T>& v1, const vector<T>& v2)
{
	vector<T>v(max(v1.size(), v2.size()));
	for (int i = 0; i < v.size(); i++)v[i] = 0;
	for (int i = 0; i < v1.size(); i++)v[i] += v1[i];
	for (int i = 0; i < v2.size(); i++)v[i] += v2[i];
	return v;
}

class Solution {
public:
	vector<int> dfs(Node* r)
	{
		vector<int> v(26);
		if (!r)return v;
		if (r->val >= 'a' && r->val <= 'z')v[r->val - 'a'] = 1;
		vector<int>v1 = dfs(r->left);
		vector<int>v2 = dfs(r->right);
		v = vecAdd(v, v1);
		v = vecAdd(v, v2);
		return v;
	}
	bool checkEquivalence(Node* r1, Node* r2) {
		vector<int> v1 = dfs(r1);
		vector<int> v2 = dfs(r2);
		for (int i = 0; i < 26; i++)if (v1[i] != v2[i])return false;
		return true;
	}
};

1634. 求两个多项式链表的和

单链表

1644. 二叉树的最近公共祖先 II

给定一棵二叉树的根节点 root,返回给定节点 p 和 q 的最近公共祖先(LCA)节点。如果 p 或 q 之一 不存在 于该二叉树中,返回 null。树中的每个节点值都是互不相同的。

根据维基百科中对最近公共祖先节点的定义:“两个节点 p 和 q 在二叉树 T 中的最近公共祖先节点是 后代节点 中既包括 p 又包括 q 的最深节点(我们允许 一个节点为自身的一个后代节点 )”。一个节点 x 的 后代节点 是节点 x 到某一叶节点间的路径中的节点 y。

示例 1:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和 1 的共同祖先节点是 3。
示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和 4 的共同祖先节点是 5。根据共同祖先节点的定义,一个节点可以是自身的后代节点。
示例 3:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 10
输出: null
解释: 节点 10 不存在于树中,所以返回 null。
 

提示:

树中节点个数的范围是 [1, 104]
-109 <= Node.val <= 109
所有节点的值 Node.val 互不相同
p != q
 

进阶: 在不检查节点是否存在的情况下,你可以遍历树找出最近公共祖先节点吗?

class Solution {
public:
	TreeNode* ans;
	int dfs(TreeNode* root, TreeNode* p, TreeNode* q)
	{
		if (!root)return 0;
		int a = dfs(root->left, p, q) + dfs(root->right, p, q);
		if (root == p || root == q)a++;
		if (a == 2 && ans == NULL)ans = root;
		return a;
	}
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		ans = NULL;
		dfs(root, p, q);
		return ans;
	}
};

1650. 二叉树的最近公共祖先 III

给定一棵二叉树中的两个节点 p 和 q,返回它们的最近公共祖先节点(LCA)。

每个节点都包含其父节点的引用(指针)。Node 的定义如下:

class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
}
根据维基百科中对最近公共祖先节点的定义:“两个节点 p 和 q 在二叉树 T 中的最近公共祖先节点是后代节点中既包括 p 又包括 q 的最深节点(我们允许一个节点为自身的一个后代节点)”。一个节点 x 的后代节点是节点 x 到某一叶节点间的路径中的节点 y。

示例 1:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和 1 的最近公共祖先是 3。
示例 2:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和 4 的最近公共祖先是 5,根据定义,一个节点可以是自身的最近公共祖先。
示例 3:

输入: root = [1,2], p = 1, q = 2
输出: 1
 

提示:

树中节点个数的范围是 [2, 105]。
-109 <= Node.val <= 109
所有的 Node.val 都是互不相同的。
p != q
p 和 q 存在于树中。

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* parent;
};
*/

#define TreeNode Node
class Solution {
public:
	TreeNode* ans;
	int dfs(TreeNode* root, TreeNode* p, TreeNode* q)
	{
		if (!root)return 0;
		int a = dfs(root->left, p, q) + dfs(root->right, p, q);
		if (root == p || root == q)a++;
		if (a == 2 && ans == NULL)ans = root;
		return a;
	}
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		ans = NULL;
		dfs(root, p, q);
		return ans;
	}
	Node* lowestCommonAncestor(Node* p, Node * q) {
		Node* h = p;
		while (h->parent)h = h->parent;
		return lowestCommonAncestor(h, p, q);
	}
};

1666. 改变二叉树的根节点

二叉树

1676. 二叉树的最近公共祖先 IV

给定一棵二叉树的根节点 root 和 TreeNode 类对象的数组(列表) nodes,返回 nodes 中所有节点的最近公共祖先(LCA)。数组(列表)中所有节点都存在于该二叉树中,且二叉树中所有节点的值都是互不相同的。

我们扩展二叉树的最近公共祖先节点在维基百科上的定义:“对于任意合理的 i 值, n 个节点 p1 、 p2、...、 pn 在二叉树 T 中的最近公共祖先节点是后代中包含所有节点 pi 的最深节点(我们允许一个节点是其自身的后代)”。一个节点 x 的后代节点是节点 x 到某一叶节点间的路径中的节点 y。

示例 1:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [4,7]
输出: 2
解释: 节点 4 和 7 的最近公共祖先是 2。
示例 2:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [1]
输出: 1
解释: 单个节点的最近公共祖先是该节点本身。

示例 3:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [7,6,2,4]
输出: 5
解释: 节点 7、6、2 和 4 的最近公共祖先节点是 5。
示例 4:


输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [0,1,2,3,4,5,6,7,8]
输出: 3
解释: 树中所有节点的最近公共祖先是根节点。

提示:

树中节点个数的范围是 [1, 104] 。
-109 <= Node.val <= 109
所有的 Node.val 都是互不相同的。
所有的 nodes[i] 都存在于该树中。
所有的 nodes[i] 都是互不相同的。

class Solution {
public:
	TreeNode* ans;
	int dfs(TreeNode* root, vector<TreeNode*> &nodes)
	{
		if (!root)return 0;
		int a = dfs(root->left, nodes) + dfs(root->right, nodes);
		if (find(nodes.begin(), nodes.end(),root)!= nodes.end())a++;
		if (a == nodes.size() && ans == NULL)ans = root;
		return a;
	}
	TreeNode* lowestCommonAncestor(TreeNode* root, vector<TreeNode*> &nodes) {
		ans = NULL;
		dfs(root, nodes);
		return ans;
	}
};

猜你喜欢

转载自blog.csdn.net/nameofcsdn/article/details/124973123