简单的做个刷题记录(大佬们勿喷)
叶子相似的树
https://leetcode-cn.com/problems/leaf-similar-trees
思路:使用深度优先搜索(或者说是先序遍历)。遍历结点,如果是叶子,那么把结点的值存储到数组里面,最后比较两个数组的节点值是否相同
class Solution {
public:
bool leafSimilar(TreeNode* root1, TreeNode* root2) {
vector<int>left;
vector<int>right;
dfs(root1,left);
dfs(root2,right);
return left==right;
}
//其实就是先序遍历
void dfs(TreeNode* root,vector<int>& temp){
if(root==NULL){
return;
}
if(root->left==NULL&&root->right==NULL){
temp.push_back(root->val);
}
dfs(root->left,temp);
dfs(root->right,temp);
}
};
I. 二叉树的深度
https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/
思路:树的高度等于max(左子树的高度,右子树高度)+1
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL)
return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}};
二叉树的最小深度
https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
思路:注意跟上一题求最大深度区分,因为本题最小深度规定是从叶子节点结束,所以像 [1,2] 这种情况,因为1不是叶子节点,所以最小深度为2不是1.
考虑递归的结束条件:
- 左右节点均为空,此时最小深度为1
- 左右节点其中之一为空,则最小深度为非空子树的深度+1,即左右节点深度的最大值+1
- 左右节点均不为空,则返回最小深度+1
/**
* 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:
int minDepth(TreeNode* root) {
if(root==NULL){
return 0;
}
//左右子树均为空
if(root->left==NULL&&root->right==NULL){
return 1;
}
//左右子树其中有一个为空
if(root->left==NULL||root->right==NULL){
return max(minDepth(root->left),minDepth(root->right))+1;
}
//左右子树均不为空
return min(minDepth(root->left),minDepth(root->right))+1;
}
};
II. 平衡二叉树
https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/
思路:判断根节点左子树和右子树的高度,比较两者的差值是否小于或者等于1,接着判断左子树的左右子树的高度差和右子树的左右子树高度差,如果都满足的话,才返回 true
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(root==NULL){
return true;
}
if(abs(maxDepth(root->left)-maxDepth(root->right))>1){
return false;
}
return isBalanced(root->left)&&isBalanced(root->right);
}
int maxDepth(TreeNode* root){
if(root==NULL){
return 0;
}
return max(maxDepth(root->left),maxDepth(root->right))+1;
}};
N叉树的最大深度
https://leetcode-cn.com/problems/maximum-depth-of-n-ary-tree/
思路:求深度的方法和上面两题类似,只是多了for循环遍历多个孩子节点
本题跟 将有序数组转换为二叉搜索树 (题目链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/)的代码一样(可以仔细体会相同解法的题目但是不同的题目设置方式)
class Solution {
public:
int maxDepth(Node* root) {
if(root==NULL){
return 0;
}
int res = 0;
for(int i = 0; i<root->children.size();i++){
//遍历每个孩子节点的深度
int hight = maxDepth(root->children[i]);
res = max(hight,res);
}
return 1+res;
}
};
最小高度树
https://leetcode-cn.com/problems/minimum-height-tree-lcci/
思路:要使得高度最小,可以选取数组的中位数(因为数组是升序排序,因此中位数就是在数组的中点部分)作为根节点,左右递归创建左右子树。
/**
* 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:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return dfs(nums,0,nums.size());
}
TreeNode* dfs(vector<int>&nums,int left,int right){
if(left==right){
return NULL;
}
int mid = (left+right)/2;
TreeNode* root = new TreeNode(nums[mid]);
root->left = dfs(nums,left,mid);
root->right = dfs(nums,mid+1,right);
return root;
}
};
路径总和
https://leetcode-cn.com/problems/path-sum/comments/
思路:深度搜索判断根节点的值是否等于sum的值,每深入一个节点,sum = sum-当前节点值,当到达叶子节点时,判断sum是否等于当前叶子节点值,如果是,说明当前路径满足题意,返回true
/**
* 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 hasPathSum(TreeNode* root, int sum) {
if(!root)
return false;
//遍历到叶子节点,且值等于target
if(root->val==sum && root->left==NULL && root->right==NULL){
return true;
}
int res = sum-root->val;
//递归判断左右节点的值是否等于sum
return hasPathSum(root->left,res)||hasPathSum(root->right,res);
}
};
相同的树
https://leetcode-cn.com/problems/same-tree/
递归条件:
- 如果两棵树均为空,返回true
- 其中一棵树不为空,返回false
- 两棵树都不为空,但是节点的值不同,返回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 isSameTree(TreeNode* p, TreeNode* q) {
if(p==NULL&&q==NULL){
return true;
}
if(p==NULL||q==NULL){
return false;
}
if(p->val!=q->val){
return false;
}
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
};
颜色填充
思路:深度搜索(sr, sc),判断相邻四个顶点是否需要进行填充,注意初始坐标点的颜色已经跟newColor相同了就不用进行填充了
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
int oldcolor = image[sr][sc];
if(image.size()==0||image[0].size()==0||oldcolor==newColor){//注意:初始坐标点的颜色已经跟新颜色相同了就不用进行填充了
return image;
}
dfs(image,sr,sc,oldcolor,newColor);
return image;
}
void dfs(vector<vector<int>>& image,int sr,int sc,int oldcolor,int newColor){
//注意:该点的颜色跟初始点的颜色不同不用判断
if(sr<0||sr>=image.size()||sc<0||sc>=image[0].size()||image[sr][sc]!=oldcolor){
return;
}
image[sr][sc] = newColor;
dfs(image,sr+1,sc,oldcolor,newColor);
dfs(image,sr-1,sc,oldcolor,newColor);
dfs(image,sr,sc+1,oldcolor,newColor);
dfs(image,sr,sc-1,oldcolor,newColor);
}
};
员工的重要性
https://leetcode-cn.com/problems/employee-importance/
递归法(一个一个找),先找到id相同的员工(根节点),再递归寻找下级员工(子节点)。思路简单但是效率不高
/*
// Definition for Employee.
class Employee {
public:
int id;
int importance;
vector<int> subordinates;
};
*/
class Solution {
public:
int getImportance(vector<Employee*> employees, int id) {
int i,sum;
for(i = 0;i<employees.size();i++){
if(id==employees[i]->id){
sum = employees[i]->importance;
break;
}
}
if(sum==0){
return 0;
}
for(int j = 0;j < (employees[i]->subordinates.size()); j++)
sum += getImportance(employees,employees[i]->subordinates[j]);
return sum;
}
};
改用map进行优化,提升查找员工的效率。
class Solution {
public:
int sum = 0;
map<int,Employee*> m;
int getImportance(vector<Employee*> employees, int id) {
for(int i = 0;i<employees.size();i++){
m[employees[i]->id] = employees[i];
}
dfs(id);
return sum;
}
void dfs(int id){
Employee* t = m.find(id)->second;
sum += t->importance;
for(int i=0;i<t->subordinates.size(); i++){
dfs(t->subordinates[i]);
}
}
};
二叉树的所有路径
https://leetcode-cn.com/problems/employee-importance/submissions/
思路:深度遍历二叉树时,如果当前的节点不是叶子节点,则末尾添加节点,并递归遍历该节点的孩子节点。如果当前的节点是叶子节点,则获得该路径。
/**
* 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:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> temp;
if(root==NULL){
return temp;
}
dfs(root,temp,"");
return temp;
}
void dfs(TreeNode* root,vector<string>& temp,string str){
str += to_string(root->val);//转化成string类型
if(root->left==NULL&&root->right==NULL){
temp.push_back(str);
return;
}
if(root->left){
dfs(root->left,temp,str+"->");
}
if(root->right){
dfs(root->right,temp,str+"->");
}
}
};
对称二叉树
https://leetcode-cn.com/problems/symmetric-tree/
思路:镜像对称就是左右子树都是相当的。假如将根节点的左右子树分为两边,左子树为左图,右子树为右图,从上图可以看出如果两棵树是镜面对称的,那么首先左右子树最上层的顶点即2要相等,其次还满足规律:左子树2的左孩子等于右子树2的右孩子,左子树2的右孩子等于右子树2的左孩子。因此通过递归比较左子树和右子树,以及它们的左右节点判断是否满足题意
递归终止条件:
- 左右子树均为空
- 左右子树之中有一个为空
- 左右子树均不为空但是左右子树的值不关于镜面对称
/**
* 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 isSymmetric(TreeNode* root) {
return judge(root,root);
}
//镜像比较
bool judge(TreeNode* l,TreeNode *r){
if(l==NULL&&r==NULL){//左右子树均为空
return true;
}
if(l==NULL||r==NULL){//左右子树之中有一个为空
return false;
}
if(l->val==r->val){
return judge(l->left,r->right)&&judge(l->right,r->left);
}else{
return false;
}
}
};
递增顺序查找树
https://leetcode-cn.com/problems/increasing-order-search-tree/
思路:中序遍历将节点的值存储到vector数组中,再重新构造一棵只有右子树的树
/**
* 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:
void inorder(TreeNode* root,vector<int>& temp){
if(root!=NULL){
inorder(root->left,temp);
temp.push_back(root->val);
inorder(root->right,temp);
}
}
TreeNode* increasingBST(TreeNode* root) {
if(root==NULL){
return NULL;
}
vector<int> res;
inorder(root,res);
TreeNode* p = new TreeNode(0);
TreeNode* q = p;
for(int i = 0;i<res.size();i++){
p->right = new TreeNode(res[i]);
p = p->right;
}
return q->right;
}
};