三十天算法突破计划 Day 1

三十天算法突破计划 Day 1

AC1

Problem,已知二叉树的前序遍历和后序遍历,求这个树的中序遍历的可能数目

思路

 首先说明两条性质

一 在前序遍历中,若一个节点只有一个子节点,那么它一定在它的子节点的前面

二 在后序遍历中,若一个节点只有一个子节点,那么它一定在它的子节点的后面

 对于一个树的前序遍历和后序遍历,我们考虑一个最小的单元,就是两个节点的树,在这个树里面,不管第二个节点是在左边还是在右边,都能得到一样的前序遍历结果和后序遍历的结果,所以在这个里面我们要找的就是只有一个支的节点。再根据上面的两个性质去进行查找有多少个单子节点的节点。

解答

#include <stdio.h>
#include <string.h>
#define N 20000
char s1[N];
char s2[N];
int ans;
int main()
{
    scanf("%s%s",s1,s2);
    for (int i = 0; i < strlen(s1)-1; i++)
        for (int j = 1; j < strlen(s2); j++)
            if(s1[i]==s2[j]&&s1[i+1]==s2[j-1]) ans++;
    // 查找我们的节点
    printf("%lld",1ll<<ans);
   // 所有的可能
}

AC2

Problem求二叉树两个节点之间的距离,宽度,深度

在这里我们要先学习一下啊LCA问题————求两个子节点的最近公共祖先。就先论述一下LCA的一种解法吧(其实目前也只会这一种)

思路:先将两个节点调整到一个高度,即让一个变为与另外一个等高度的祖先,然后二者必然有一个公共祖先,他们的距离必然可以用一个二进制的数进行表示,需要跳跃的次数可以表示2的几种幂之和。

LCA模版题 ,大家不了解的可以去切题

下面是AC的代码

#include <stdio.h>
#include <iostream>
using namespace std;
#define N 1000
int lg[N];
int fa[N][N];
int dep[N];
struct node
{
    int depth;
    int father;
}node[N];
int cnt = 0;
int Lca(int x,int y)
{
    if(node[x].depth < node[y].depth)
        swap(x, y);
    while (node[x].depth > node[y].depth)
    {
        x = fa[x][lg[node[x].depth - node[y].depth]];
    }
    if(x==y) return x;
    for (int i = lg[node[x].depth]; i>=0; i--)
    {
       // printf("%d %d\n",fa[x][i-1],fa[y][i-1]);
        if(fa[x][i]!=fa[y][i])
        {
            x = fa[x][i];
            y = fa[y][i];
        }
    }
    return fa[x][0];
}
// 上面这一部分是倍增的LCA代码
int main()
{
    lg[0] = 0;
    for(int i = 1; i < N; ++i) //预先算出log_2(i)的值,用的时候直接调用就可以了
          lg[i] = lg[i-1] + (1 <<(lg[i-1]+1) == i);  //看不懂的可以手推一下
    int n,x,y;
    int Depth = 0;
    scanf("%d",&n);
    node[1].depth = 1;
    for (int i = 1; i < n; i++)
    {
        scanf("%d%d",&x,&y);
        node[y].father = x;
        node[y].depth = node[x].depth+1;
        Depth = max(Depth,node[y].depth);
        fa[y][0] = x;
        for (int i = 1; i <= lg[node[y].depth]; i++)
        {
            fa[y][i] = fa[fa[y][i-1]][i-1];
        }
        dep[node[x].depth]++;
        // 查找每个数的第2^i个祖先
    }
    int kuan = 0;
    for (int i = 1; i <= Depth; i++)
    {
        kuan = max(kuan,dep[i]);
    }
    scanf("%d%d",&x,&y);
    int LCA = Lca(x, y);
    printf("%d\n",Depth);
    printf("%d\n",kuan);
    printf("%d",2*abs(node[x].depth - node[LCA].depth) + abs(node[y].depth - node[LCA].depth));
    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值