腾讯音乐娱乐集团2024校园招聘-前端开发笔试(II)

小红的二叉树计数

题目描述

小红定义一个二叉树为“好二叉树”,当且仅当该二叉树所有节点的孩子数量为偶数( 0 0 0 或者 2 2 2)。小红想知道, n n n 个节点组成的好二叉树,共有多少种不同的形态?答案请对 1 0 9 + 7 10^9+7 109+7 取模。

数据范围
  • 1 ≤ n ≤ 3000 1 ≤ n ≤ 3000 1n3000
解题思路
  1. 所有好二叉树的节点的数量均为奇数;
  2. 一棵二叉树的形态由其左子树和右子树的形态决定。
代码实现
int cntOfTrees(int n) {
    const int N = 3e3 + 5, MOD = 1e9 + 7;
    long long dp[N] = {0};
    // 节点个数为偶数时无法构成好二叉树
    if (!(n & 1)) return 0;
    dp[1] = dp[3] = 1;
    for (int i = 5; i <= n; i += 2) {
        for (int j = 1, k = i - 1; j < k; j += 2) {
            dp[i] += (dp[j] * dp[k - j]) % MOD;
            dp[i] %= MOD;
        }
    }
    return (int) dp[n];
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n 2 ) O(n^2) O(n2)

小红的可爱串

题目描述

小红定义一个字符串是可爱串,当且仅当该字符串包含子序列 r e d red red,且不包含子串 r e d red red

我们定义子序列为字符串中可以不连续的一段,而子串则必须连续。例如 r d e r d rderd rderd 包含子序列 r e d red red,且不包含子串 r e d red red,因此该字符串为可爱串。

小红想知道,长度为 n n n 的、仅由 r r r e e e d d d 三种字母组成的字符串中,有多少是可爱串?答案请对 1 0 9 + 7 10^9+7 109+7 取模。

数据范围
  • 1 ≤ n ≤ 1 0 5 1 ≤ n ≤ 10^5 1n105
解题思路
  1. 包含子串 r e d red red 的字符串的集合 ∈ 包含子序列 r e d red red 的字符串集合。

  2. 可爱串的数量 = 包含子序列 r e d red red 的字符串的数量 - 包含子串 r e d red red 的字符串的数量 。

  3. 如何构造包含子串 r e d red red 的字符串(记字符串为 s s s) ?

    • f [ i ] f[i] f[i] = 长度为 i i i 的字符串中包含子串 r e d red red 的字符串的数量。
    • 分为两种情况
      • s [ i ] s[i] s[i] r r r e e e,则 s [ i ] s[i] s[i] 必定不影响 f [ i ] f[i] f[i] f [ i ] = f [ i − 1 ] + f [ i − 1 ] f[i] = f[i-1] + f[i-1] f[i]=f[i1]+f[i1]
      • s [ i ] s[i] s[i] d d d
        • 若 $s[i] $ 不影响 f [ i ] f[i] f[i],即 s [ 1.. i − 1 ] s[1..i-1] s[1..i1] 已包含子串 r e d red red,则$ f[i] = f[i-1]$。
        • 若 $s[i] $ 影响 f [ i ] f[i] f[i],即 s [ 1.. i − 3 ] s[1..i-3] s[1..i3] 不含子串 r e d red red,但 s [ i − 2.. i − 1 ] = r e s[i-2..i-1]= re s[i2..i1]=re,加上 s [ i ] s[i] s[i] 即可构成子串 r e d red red,则$ f[i] = 3^{(i-3)}-f[i-3]$。
    • 综上, f [ i ] = 3 × f [ i − 1 ] + 3 ( i − 3 ) − f [ i − 3 ] f[i] = 3 \times f[i-1] + 3^{(i-3)}-f[i-3] f[i]=3×f[i1]+3(i3)f[i3]
  4. 如何构造包含子序列 r e d red red 的字符串(记字符串为 s)?

    • g [ i ] g[i] g[i] = 长度为 i i i 的字符串中包含子序列 r e d red red 的字符串的数量。
    • 分为两种情况
      • s [ i ] s[i] s[i] r r r e e e,则 s [ i ] s[i] s[i] 必定不影响 g [ i ] g[i] g[i] g [ i ] = g [ i − 1 ] + g [ i − 1 ] g[i] = g[i-1] + g[i-1] g[i]=g[i1]+g[i1]
      • s [ i ] s[i] s[i] d d d
        • 若 $s[i] $ 不影响 g [ i ] g[i] g[i],即 s [ 1.. i − 1 ] s[1..i-1] s[1..i1] 已包含子序列 r e d red red,则 g [ i ] = g [ i − 1 ] g[i] = g[i-1] g[i]=g[i1]
        • 若 $s[i] $ 影响 g [ i ] g[i] g[i],即 s [ 1.. i − i ] s[1..i-i] s[1..ii] 不含子序列 r e d red red,但含子序列 r e re re,加上 s [ i ] s[i] s[i] 即可构成子序列 r e d red red,令 h [ i ] h[i] h[i] = 长度为 i i i 的字符串中不含子序列 r e d red red但含子序列 r e re re 的字符串的数量,则 g [ i ] = h [ i − 1 ] g[i] = h[i-1] g[i]=h[i1]
      • 综上所述, g [ i ] = 3 × g [ i − 1 ] + h [ i − 1 ] g[i] = 3 \times g[i-1] + h[i-1] g[i]=3×g[i1]+h[i1]
  5. 如何构造不含子序列 r e d red red且含子序列 r e re re 的字符串,即如何计算 f [ i ] f[i] f[i](记字符串为 s)?

    • h [ i ] h[i] h[i] = 长度为 i i i 的字符串中不含子序列 r e d red red 但含子序列 r e re re 的字符串的数量(第4点中已进行如此假设)。

    • s [ i ] s[i] s[i] 是否能为 d d d?包含子序列 r e re re、不包含子序列 r e d red red s [ i ] = d s[i] = d s[i]=d,满足这三个条件的字符串不存在,故不考虑 s [ i ] = d s[i] = d s[i]=d 的情况。

    • 分为两种情况

      • s [ i ] s[i] s[i] r r r,则 s [ i ] s[i] s[i] 必定不影响 h [ i ] h[i] h[i] h [ i ] = h [ i − 1 ] h[i] = h[i-1] h[i]=h[i1]

      • s [ i ] s[i] s[i] e e e

        • s [ i ] s[i] s[i] 不影响 h [ i ] h[i] h[i],即 s [ 1.. i − 1 ] s[1..i-1] s[1..i1] 已包含子序列 r e re re 且不含子序列 r e d red red,则 h [ i ] = h [ i − 1 ] h[i] = h[i-1] h[i]=h[i1]

        • s [ i ] s[i] s[i] 影响 h [ i ] h[i] h[i],即 s [ 1.. i − 1 ] s[1..i-1] s[1..i1] 不满足(已包含子序列 r e re re 且不含子序列 r e d red red),但含有子序列 r r r,加上 s [ i ] s[i] s[i] 即可构成子序列 r e re re

          令条件 A A A = 不满足(已包含子序列 r e re re 且不含子序列 r e d red red)但含有子序列 r r r,设满足条件 A A A 的字符串为 t t t,下面考虑如何构造 t t t

          t t t 的长度为 i − 1 i-1 i1 t t t 至少包含一个子序列 r r r,手动将一个子序列 r r r 填入 t t t,记作 R R R,并规定手动填入的 R R R 的左边空位不能填入 r r r R R R i − 1 i-1 i1 个位置可以选择,以 R R R 为界

          • R R R 左边的空位只可填入 e e e d d d,这是因为,为了防止重复计算,人为规定 R R R 的左边空位不能填 r r r
          • R R R 右边的空位只可填入 r r r d d d,这是因为, R R R 右边空位若填入 e e e,则 s [ 1.. i − 1 ] s[1..i-1] s[1..i1] 则含有子序列 r e re re s [ i ] s[i] s[i] h [ i ] h[i] h[i] 无影响,这与前置条件相矛盾,故 R R R 右边空位不可以填入 e e e

          经过分析, R R R 左边和右边空位均只可以填入两种字符,共有 i − 2 i-2 i2 个空位,共有 2 ( i − 2 ) 2^{(i-2)} 2(i2) 种填充方式,又因为 R R R i − 1 i-1 i1 中填充方式,故 t t t 的数量有 $(i-1) \times 2^{(i-2)} $,也即 h [ i ] = ( i − 1 ) × 2 ( i − 2 ) h[i] = (i-1) \times 2^{(i-2)} h[i]=(i1)×2(i2)

      • 综上所述, h [ i ] = 2 × h [ i − 1 ] + ( i − 1 ) × 2 ( i − 2 ) h[i] = 2 \times h[i-1] + (i-1) \times 2^{(i-2)} h[i]=2×h[i1]+(i1)×2(i2)

  6. 综上所述,长度为 n n n 的可爱串的数量为 g [ n ] − f [ n ] g[n]-f[n] g[n]f[n]

代码实现
typedef long long ll;
const int N = 1e5 + 5, MOD = 1e9 + 7;
ll f[N], g[N], h[N];

// 快速幂
ll ksm(ll x, ll n) {
    ll res = 1 % MOD;
    while (n) {
        if (n & 1)res = res * x % MOD;
        x = x * x % MOD;
        n >>= 1;
    }
    return res;
}

int kawaiiStrings(int n) {
    // f[i] = 长度为 i 的字符串中包含子串 red 的字符串的数量
    for (int i = 3; i <= n; i++)
        f[i] = (f[i - 1] * 3 + ksm(3, i - 3) - f[i - 3]) % MOD;
    // h[i] = 长度为 i 的字符串中不含子序列 red 但含子序列 re 的字符串的数量
    for (int i = 2; i <= n; i++)
        h[i] = (h[i - 1] * 2 + (i - 1) * ksm(2, i - 2)) % MOD;
    // g[i] = 长度为 i 的字符串中包含子序列 red 的字符串
    for (int i = 3; i <= n; i++)
        g[i] = (g[i - 1] * 3 + h[i - 1]) % MOD;
    return int((g[n] - f[n] + MOD) % MOD);
}

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( n ) O(n) O(n)

小红的元素乘积

题目描述

小红定义一个数为“完美数”,当且仅当该数仅有一个非零数字。例如 5000 , 4 , 1 , 10 , 200 5000,4,1,10,200 5000,4,1,10,200 都是完美数。小红拿到了一个大小为 n n n 的数组,她希望选择两个元素,满足它们的乘积为完美数。小红想知道,共有多少种不同的取法?

数据范围
  • 1 ≤ n ≤ 2000 1 ≤ n ≤ 2000 1n2000
  • 1 ≤ a i ≤ 1 0 9 1 ≤ a_i ≤ 10^9 1ai109
解题思路

枚举判断即可。

代码实现
typedef long long ll;

bool check(ll x) {
    if (x < 10)return true;
    string s = to_string(x);
    for (int i = 1; i < s.size(); i++)
        if (s[i] != '0')return false;
    return true;
}

int perfectPair(vector<int> &arr) {
    int n = arr.size(), res = 0;
    if (n < 2)return 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (check((ll) arr[i] * arr[j]))res++;
        }
    }
    return res;
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( 1 ) O(1) O(1)

END

题目来源:腾讯音乐娱乐集团2024校园招聘-前端开发笔试(II)

文章声明:题目来源 牛客 平台,如有侵权,请联系删除!

文章文档:公众号 字节幺零二四 回复关键字可获取本文文档。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值