2021-11-01每日刷题打卡

2021-11-01每日刷题打卡

力扣——二叉树

965. 单值二叉树

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。

只有给定的树是单值二叉树时,才返回 true;否则返回 false。

示例 1:

screen-shot-2018-12-25-at-50104-pm.png

输入:[1,1,1,1,1,null,1]
输出:true

这题考的就是树的遍历,比起链表的一个指针next,树有两个指针一个left,一个right。对于树的遍历我们最好用的就是递归的方式。全局变量设定一个bool类型flag初始化为true,每次遍历对比当前节点的val和其left与right的val值,如果不相等就设为false并直接结束所有程序返回flag,如果相等,就把root->left和root->right放入遍历中。最后返回flag。

/**
 * 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:
    bool flag=true;
    bool isUnivalTree(TreeNode* root) {
        if(root==NULL)return flag;
        if(root->left!=NULL)
        {
            if(root->val!=root->left->val)flag=false;
            isUnivalTree(root->left);
        }
        if(root->right!=NULL)
        {
            if(root->val!=root->right->val)flag=false;
            isUnivalTree(root->right);
        }
        return flag;
    }
};

另一种方法,不用全局变量。

/*
 * 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:
    bool isUnivalTree(TreeNode* root) {
        bool flag=true;
        int val=root->val;
        dfs(root,flag,val);
        return flag;
    }
    void dfs(TreeNode* root,bool &flag,int val)
    {
        if(root==NULL)return;
        if(root->left!=NULL&&root->left->val!=val)flag=false;
        if(root->right!=NULL&&root->right->val!=val)flag=false;
        dfs(root->left,flag,val);
        dfs(root->right,flag,val);
    }
};
100. 相同的树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

ex1.jpg (622×182) (leetcode.com)

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

还是遍历树,不过这次是同时遍历两个,还要对比他们的val值。注意有一点,对比root->val时要考虑到节点为NULL的情况,这会使程序报错,所以对比值前我们应该先判断一下两个节点是否为NULL,如果两个都为NULL那就直接return结束程序,如果只有一个为空就把flag改为false(一个节点有值一个节点没值肯定不一样),如果都不为空就对比val。

/**
 * 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:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        bool flag=true;
        dfs(p,q,flag);
        return flag;
    }
    void dfs(TreeNode* p, TreeNode* q,bool &flag) {
        if(!flag)return;
        if(p==NULL&&q==NULL)return;
        else if(p==NULL&&q!=NULL||p!=NULL&&q==NULL)
        {
            flag=false;
            return;
        }
        if(p->val!=q->val)flag=false;
        dfs(p->left,q->left,flag);
        dfs(p->right,q->right,flag);
    }
};
101. 对称二叉树剑指 Offer 28. 对称的二叉树(这两题完全一样,我们放在一起说)

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

​ 1

/
2 2
/ \ /
3 4 4 3

这题就是上题的翻版,不过上题比较的是相同的子节点,即left和left比,right和right比。这题是left和right比,right和left比。

/**
 * 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:
    bool isSymmetric(TreeNode* root) {
        bool flag=true;
        dfs(root->left,root->right,flag);
        return flag;
    }
    void dfs(TreeNode *p,TreeNode*q,bool &flag)
    {
        if(!flag)return;
        if(!p&&!q)return;
        else if(!p&&q || p&&!q)
        {
            flag=false;
            return;
        }
        if(p->val!=q->val)flag=false;
        dfs(p->left,q->right,flag);
        dfs(p->right,q->left,flag);
    }
};

AcWing——算法基础

842. 排列数字 - AcWing题库

给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。

现在,请你按照字典序将所有的排列方法输出。

输入格式

共一行,包含一个整数 n。

输出格式

按字典序输出所有排列方案,每个方案占一行。

数据范围

1≤n≤7

输入样例:
3
输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

这是我们第一次接触到DFS(深度优先搜索):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将 回溯 到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。

这里排列数字的过程就是,我们要组成一个三位数的数字,第一位的可能性有1、2、3,我们先选1,第二位的可能性就剩2、3,我们选2,第三位就只剩3了,这条路搜索完毕,我们回溯到第二位上,选3为第二位,这样第三位就只剩2了,这条路也搜索完毕,我们回溯到第二位上,第二位可能的结果也都搜索完,我们回溯到第一位上,选数字2为第一位,然后继续搜…………这样最后我们就可以拿到所有的数。

我们准备一个int数组math来存放结果,一个bool数组st来告诉我们哪些数不能用,写一个递归函数dfs来进行我们的搜索,只有一个参数u,dfs进来先判断u和n是否相同,如果相同则输出math里存放的结果(要注意换行)。如果不相同我们就开始for(int i=0;i<n;i++)遍历,,判断st[i]的值是否为true,如果为true说明i表示的数我们已经使用过了,如果为false说明这个数我们没用过,可以放在第u位上,所有我们math[u]=i,同时把st[i]改为true告诉程序这个数已经被用过了。然后我们递归调用dfs(u+1),下面是回溯的操作,我们要把数变回原来的样子,即这个数没被使用过的样子st[i]=false。这样我们最后就能获得所有的结果。

#include<iostream>
using namespace std;

const int N=100010;
int n;
int math[N];
bool st[N];

void dfs(int u)
{
    if(u==n)
    {
        for(int i=0;i<n;i++)printf("%d ",math[i]);
        cout<<endl;
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(!st[i])
        {
            st[i]=true;
            math[u]=i;
            dfs(u+1);
            st[i]=false;
        }
    }
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)scanf("%d",&math[i]);
    dfs(0);
    return 0;
}
843. n-皇后问题 - AcWing题库

n−n−皇后问题是指将 n 个皇后放在 n×n的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

1_597ec77c49-8-queens.png

现在给定整数 n,请你输出所有的满足条件的棋子摆法。

输入格式

共一行,包含整数 n。

输出格式

每个解决方案占 n 行,每行输出一个长度为 nn 的字符串,用来表示完整的棋盘状态。

其中 . 表示某一个位置的方格状态为空,Q 表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

注意:行末不能有多余空格。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围

1≤n≤9

输入样例:
4
输出样例:
.Q..
...Q
Q...
..Q.

..Q.
Q...
...Q
.Q..

DFS中最最最最最最最最最经典的八皇后问题,我们用的就是深度优先搜索的方法来写这道题,拿一个二维数组来模拟棋盘的样子,Q代表皇后的位置,我们的想法是先把皇后放在所有可能的地方上,每放一个皇后,就判断这个皇后同行同列同斜列上有没有皇后,如果有就说明这个方法不可行,然后回溯,然后再选新地方放…………以此类推。

#include<iostream>
using namespace std;

const int N=100;
int n;
char queen[N][N];
bool col[N],dg[N],udg[N];

void dfs(int u)
{
    if(u==n)
    {
        for(int i=0;i<n;i++)cout<<queen[i]<<endl;
        cout<<endl;
        return;
    }
    for(int i=0;i<n;i++)
    {
        if(!col[i]&&!dg[i+u]&&!udg[n-u+i])
        {
            queen[u][i]='Q';
            col[i]=dg[u+i]=udg[n-u+i]=true;
            dfs(u+1);
            col[i]=dg[u+i]=udg[n-u+i]=false;
            queen[u][i]='.';
        }
    }
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            queen[i][j]='.';
    dfs(0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值