1.
给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表。
如果在二叉树中,存在一条一直向下的路径,且每个点的数值恰好一一对应以 head 为首的链表中每个节点的值,那么请你返回 True ,否则返回 False 。
一直向下的路径的意思是:从树中某个节点开始,一直连续向下的路径。
示例 1:
输入:
head = [4,2,8],
root =[1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
解释:树中蓝色的节点构成了与链表对应的子路径。
示例 2:
输入:
head = [1,4,2,6],
root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
示例 3:
输入:
head = [1,4,2,6,8],
root [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:false
解释:二叉树中不存在一一对应链表的路径。
提示:
二叉树和链表中的每个节点的值都满足 1 <= node.val <= 100 。
链表包含的节点数目在 1 到 100 之间。
二叉树包含的节点数目在 1 到 2500 之间。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubPath(ListNode* head, TreeNode* root) {
if(head==nullptr)return true;
if(root==nullptr)return false;
return dfs(head,root)||isSubPath(head,root->left)||isSubPath(head,root->right);
}
bool dfs(ListNode* head, TreeNode* root){
if(head==nullptr)return true;
if(root==nullptr)return false;
if(head->val!=root->val)return false;
return dfs(head->next,root->left)||dfs(head->next,root->right);
}
};
2.
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:
[ 3,9,20,null,null,15,7],
返回其层次遍历结果:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//dfs
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> levelOrder(TreeNode* root) {
dfs(root,0);
return res;
}
void dfs(TreeNode* root,int level)
{
if(!root)return;
vector<int> que;
if(level>=res.size())
res.push_back(que);
res[level].push_back(root->val);
dfs(root->left,level+1);
dfs(root->right,level+1);
}
};
//bfs
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root)return {};
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int CurrentLevel = q.size();
vector<int> que;
for(int i=0;i<CurrentLevel;i++){
TreeNode* node=q.front();
q.pop();
que.push_back(node->val);
if(node->left)q.push(node->left);
if(node->right)q.push(node->right);
}
res.push_back(que);
}
return res;
}
};
3.
本题用到了一个数据结构叫做并查集,不了解并查集的可以先去网上学习,推介一个视频,本人当时就是通过该视频学习的并查集。
信息学竞赛教程 第一讲 并查集 中文版
在本问题中, 树指的是一个连通且无环的无向图。
输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, …, N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。
结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。
返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。
示例 1:
示例 2:
注意:
输入的二维数组大小在 3 到 1000。
二维数组中的整数在1到N之间,其中N是输入数组的大小。
class Solution {
public:
vector<int> findRedundantConnection(vector<vector<int>>& edges) {
vector<int> bcj(1001);
int size=edges.size();
for(int i=1;i<=size;i++)
bcj[i]=i;
for(int i=0;i<size;i++)
{
int ret1=Find(edges[i][0],bcj);
int ret2=Find(edges[i][1],bcj);
if(ret1!=ret2)
bcj[ret2]=ret1;
else
return edges[i];
}
return {0,0};
}
int Find(int n,vector<int> &bcj)
{
if(n==bcj[n])return n;
int num=bcj[n];
return bcj[num]=Find(num,bcj);
}
};
4.
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
返回 false 。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool state=true;
bool isBalanced(TreeNode* root) {
dfs(root);
return state;
}
void dfs(TreeNode* root){
int m_nLeft=0;
int m_nRight=0;
if(!root)return;
if(root->left!=nullptr)m_nLeft=lenght(root->left);
if(root->right!=nullptr)m_nRight=lenght(root->right);
if(abs(m_nLeft-m_nRight)>1){
state=false;
return;
}
dfs(root->left);
dfs(root->right);
}
int lenght(TreeNode* root){
if(!root)return 0;
return max(lenght(root->left),lenght(root->right))+1;
}
};
5.
给定一棵二叉树,设计一个算法,创建含有某一深度上所有节点的链表(比如,若一棵树的深度为 D,则会创建出 D 个链表)。返回一个包含所有深度的链表的数组。
示例:
输入:[1,2,3,4,5,null,7,8]
输出:[[1],[2,3],[4,5,7],[8]]
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<ListNode*> res;
vector<ListNode*> point;//保存每层链表最后一项的地址
vector<ListNode*> listOfDepth(TreeNode* tree) {
dfs(tree,0);
return res;
}
void dfs(TreeNode* tree,int level){
if(tree==nullptr)return;
ListNode* k=new ListNode();
k->val=tree->val;
k->next=nullptr;
if(level>=res.size()){
res.push_back(k);
point.push_back(k);
}
else
{
point[level]->next=k;
point[level]=k;
}
dfs(tree->left,level+1);
dfs(tree->right,level+1);
}
};
6.
给定一个 N 叉树,返回其节点值的前序遍历。
例如,给定一个 3叉树 :
返回其前序遍历: [1,3,5,6,2,4]。
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public:
vector<int> res;
vector<int> preorder(Node* root) {
dfs(root);
return res;
}
void dfs(Node* root){
if(!root)return;
res.push_back(root->val);
for(auto i:root->children){
dfs(i);
}
}
};
7.
最大树定义:一个树,其中每个节点的值都大于其子树中的任何其他值。
给出最大树的根节点 root。
就像之前的问题那样,给定的树是从表 A(root = Construct(A))递归地使用下述 Construct(A) 例程构造的:
如果 A 为空,返回 null
否则,令 A[i] 作为 A 的最大元素。创建一个值为 A[i] 的根节点 root
root 的左子树将被构建为 Construct([A[0], A[1], …, A[i-1]])
root 的右子树将被构建为 Construct([A[i+1], A[i+2], …, A[A.length - 1]])
返回 root
请注意,我们没有直接给定 A,只有一个根节点 root = Construct(A).
假设 B 是 A 的副本,并附加值 val。保证 B 中的值是不同的。
返回 Construct(B)。
We are given the root node of a maximum tree: a tree where every node has a value greater than any other value in its subtree.
Just as in the previous problem, the given tree was constructed from an list A (root = Construct(A)) recursively with the following Construct(A) routine:
If A is empty, return null.
Otherwise, let A[i] be the largest element of A. Create a root node with value A[i].
The left child of root will be Construct([A[0], A[1], …, A[i-1]])
The right child of root will be Construct([A[i+1], A[i+2], …, A[A.length - 1]])
Return root.
Note that we were not given A directly, only a root node root = Construct(A).
Suppose B is a copy of A with the value val appended to it. It is guaranteed that B has unique values.
Return Construct(B).
示例 1:
输入:root = [4,1,3,null,null,2], val = 5
输出:[5,4,null,1,3,null,null,2]
解释:A = [1,4,2,3], B = [1,4,2,3,5]
示例 2:
输入:root = [5,2,4,null,1], val = 3
输出:[5,2,4,null,1,null,3]
解释:A = [2,1,5,4], B = [2,1,5,4,3]
示例 3:
输入:root = [5,2,3,null,1], val = 4
输出:[5,2,4,null,1,3]
解释:A = [2,1,5,3], B = [2,1,5,3,4]
解释:
插入值大于根节点的值,则插入值变成根,原跟变成新根的左儿子 ;否则从根节点的右子树继续寻找,直到找到比插入值小的节点的值,将该节点作为插入值的左儿子,重构该树。
/**
* 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* insertIntoMaxTree(TreeNode* root, int val) {
if(!root)return new TreeNode(val);
if(val>=root->val)
{
TreeNode* res=new TreeNode(val,root,nullptr);
root=res;
}
else if(!root->right)
root->right=new TreeNode(val);
else
{
root->right=insertIntoMaxTree(root->right,val);
}
return root;
}
};
8.
二叉树的中序遍历
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[2,1]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
//递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<Integer> ();
fnc(root,res);
return res;
}
public void fnc(TreeNode root,List<Integer> res)
{
if(root==null)return;
fnc(root.left,res);
res.add(root.val);
fnc(root.right,res);
}
}
//迭代
//递归算法中,在JAVA虚拟机中隐式维护了一个栈,迭代方法中将栈显式表达出来
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
Deque<TreeNode> stk = new LinkedList<TreeNode>();
while (root != null || !stk.isEmpty()) {
while (root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
9.(考察同8)
递增顺序查找树
给你一个树,请你 按中序遍历 重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有一个右子结点。
示例 :
提示:
给定树中的结点数介于 1 和 100 之间。
每个结点都有一个从 0 到 1000 范围内的唯一整数值。
//递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode increasingBST(TreeNode root) {
List<Integer> res=new ArrayList<Integer>();
fnc(root,res);
return fnc1(res);
}
//求中序遍历
public void fnc(TreeNode root,List<Integer> res){
if(root==null)return;
fnc(root.left,res);
res.add(root.val);
fnc(root.right,res);
}
//得到新的树
public TreeNode fnc1(List<Integer> res){
if(res.isEmpty())return null;
TreeNode root=new TreeNode(res.get(0));
TreeNode move=root;
for(int i=1;i<res.size();i++){
TreeNode node=new TreeNode(res.get(i));
move.right=node;
move=node;
}
return root;
}
}
//迭代
class Solution {
public TreeNode increasingBST(TreeNode root) {
if(root==null)return null;
TreeNode res=new TreeNode();
TreeNode move=res;
Stack <TreeNode> st = new Stack<TreeNode>();
while(root!=null||!st.empty()){
while(root!=null){
st.push(root);
root=root.left;
}
TreeNode node=new TreeNode(st.peek().val);
move.right=node;
move=node;
root=st.pop().right;
}
return res.right;
}
}