【腾讯音乐笔试题汇总】2024-04-18-腾讯音乐春招笔试题-三语言题解(CPP/Python/Java)

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员

✨ 本系列打算持续跟新腾讯音乐近期的春秋招笔试题汇总~

💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导

👏 感谢大家的订阅➕ 和 喜欢💗

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新,5月1日之前限时免费提供ing~

💽 01.卢小姐的链表织零术

问题描述

卢小姐在学习编程时遇到了一个有趣的链表操作问题。她需要在一个单向链表的每两个相邻节点之间插入一个值为 0 的新节点。她想要一个程序,能够对任意给定的链表执行这一操作,并输出修改后的链表。

输入格式

第一行包含一个正整数 n n n,表示链表的长度。

第二行共 n n n 个空格分隔的正整数 v a l 1 , v a l 2 , . . . , v a l n val_1, val_2, ..., val_n val1,val2,...,valn,表示链表中各个节点的值。

输出格式

输出共 2 n − 1 2n-1 2n1 个空格分隔的正整数,表示插入 0 后的链表中各个节点的值。

样例输入

{1,2,3,1}

样例输出

{1,0,2,0,3,0,1}

数据范围

1 ≤ n ≤ 1000 1 \leq n \leq 1000 1n1000

0 ≤ v a l i ≤ 10000 0 \leq val_i \leq 10000 0vali10000

题解

要解决这个问题,我们需要遍历给定的链表,并在每两个相邻节点之间插入一个值为 0 的新节点。这个过程需要细心处理链表节点的指针,以确保新插入的节点正确地连接到链表中。在链表的末尾,我们不需要添加新的节点。

参考代码

  • Python
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

def insert0(head):
    dummy = ListNode(-1)
    p = dummy
    while head:
        p.next = ListNode(head.val)
        head = head.next
        p = p.next
        if head:
            p.next = ListNode(0)
            p = p.next
    return dummy.next
  • Java
class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public class Solution {
    public ListNode insert0(ListNode head) {
        ListNode dummy = new ListNode(-1), p = dummy;
        while (head != null) {
            p.next = new ListNode(head.val);
            p = p.next;
            if (head.next != null) {
                p.next = new ListNode(0);
                p = p.next;
            }
            head = head.next;
        }
        return dummy.next;
    }
}
  • Cpp
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    ListNode* insert0(ListNode* head) {
        ListNode dummy(-1), *p = &dummy;
        while (head) {
            p->next = new ListNode(head->val);
            p = p->next;
            if (head->next) {
                p->next = new ListNode(0);
                p = p->next;
            }
            head = head->next;
        }
        return dummy.next;
    }
};

💾 02.卢小姐的平衡二叉树挑战

问题描述

卢小姐在数据结构课程中学到了二叉树的概念,她现在想要构造一个特殊的满二叉树。这棵二叉树需要满足一个条件:每一层的节点权值和都相等。卢小姐希望你能帮助她构造这样一棵树,树的层数为 n n n,并且每个节点的权值都是不超过 10000 的正整数。如果有多种构造方法,返回任意一种即可。

输入格式

输入只有一行,包含一个正整数 n n n,表示二叉树的层数。

输出格式

输出一行,表示二叉树的层序遍历结果。每个节点的值之间用空格分隔。

样例输入

3

样例输出

4 2 2 1 1 1 1

数据范围

1 ≤ n ≤ 14 1 \leq n \leq 14 1n14

题解

为了构造满足条件的二叉树,我们可以采用层序遍历的方式构建树。从根节点开始,每向下一层,节点的值都是上一层节点值的一半。这样可以保证每一层的节点权值和相等。具体实现时,我们可以使用队列来辅助节点的插入和遍历。

参考代码

  • Python
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

def create_balanced_tree(n):
    if n == 0:
        return None
    root = TreeNode(1 << (n - 1))
    queue = [root]
    for level in range(n - 1, 0, -1):
        next_queue = []
        for node in queue:
            node.left = TreeNode(1 << (level - 1))
            node.right = TreeNode(1 << (level - 1))
            next_queue.extend([node.left, node.right])
        queue = next_queue
    return root
  • Java
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class Solution {
    public TreeNode createBalancedTree(int n) {
        if (n == 0) return null;
        TreeNode root = new TreeNode(1 << (n - 1));
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        for (int level = n - 1; level > 0; level--) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                node.left = new TreeNode(1 << (level - 1));
                node.right = new TreeNode(1 << (level - 1));
                queue.add(node.left);
                queue.add(node.right);
            }
        }
        return root;
    }
}
  • Cpp
struct TreeNode {
    int val;
    TreeNode *left, *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    TreeNode* createBalancedTree(int n) {
        if (n == 0) return nullptr;
        TreeNode* root = new TreeNode(1 << (n - 1));
        queue<TreeNode*> queue;
        queue.push(root);
        for (int level = n - 1; level > 0; level--) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = queue.front(); queue.pop();
                node->left = new TreeNode(1 << (level - 1));
                node->right = new TreeNode(1 << (level - 1));
                queue.push(node->left);
                queue.push(node->right);
            }
        }
        return root;
    }
};

💿 03.卢小姐的红色记忆

问题描述

卢小姐在整理她的珍贵收藏时,发现了一串珍珠链,每颗珍珠都有一个特定的价值。部分珍珠已被染成红色,而其他珍珠则保持原色。卢小姐希望通过染色使得所有红色珍珠的价值总和为偶数。她可以选择染色任意未染色的珍珠,你能帮助她计算出有多少种染色方案吗?

输入格式

第一行包含一个整数数组,表示珍珠链上每颗珍珠的价值。
第二行是一个字符串,表示每颗珍珠的颜色状态,‘R’ 表示已经被染成红色,‘W’ 表示未被染色。

输出格式

输出一个整数,表示使得所有红色珍珠的价值总和为偶数的染色方案数,结果对 1 0 9 + 7 10^9 + 7 109+7 取模。

样例输入

[1, 2, 3]
"RWW"

样例输出

2

数据范围

  • 链表长度不超过 100 100 100
  • 珍珠的价值为正整数。

题解

在这个问题中,我们需要关注两类珍珠:已经染成红色的和未染色的。首先,我们计算所有已染红珍珠的价值总和。接下来,我们需要考虑如何通过选择染色未染色的珍珠来调整总和的奇偶性。

我们将未染色的珍珠根据其价值的奇偶性分类,统计奇数价值珍珠和偶数价值珍珠的数量。基于当前红色珍珠价值总和的奇偶性,我们可以确定需要从未染色的奇数珍珠中选择某些珍珠进行染色以达到目标。

具体的计算方法是使用组合数学中的组合公式来计算选择某些珍珠染色的方案数。最后,将所有可能的选择方案累加起来即可得到最终的答案。

参考代码

  • Python
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

def getMethod(head: ListNode, colors: str) -> int:
    mod = 10 ** 9 + 7
    values = []
    while head:
        values.append(head.val)
        head = head.next
    odd_count = even_count = 0
    current_sum = 0
    for value, color in zip(values, colors):
        if color == 'R':
            current_sum += value
        else:
            if value % 2 == 1:
                odd_count += 1
            else:
                even_count += 1
    n = odd_count
    fac = [1] * (n + 10)
    ifac = [1] * (n + 10)
    for i in range(1, n + 6):
        fac[i] = fac[i - 1] * i % mod
    ifac[n + 5] = pow(fac[n + 5], mod - 2, mod)
    for i in range(n + 5, 0, -1):
        ifac[i - 1] = ifac[i] * i % mod

    def combine(n, m):
        if n < m or m < 0:
            return 0
        return fac[n] * ifac[m] % mod * ifac[n - m] % mod

    result = 0
    power_of_two = pow(2, even_count, mod)
    if current_sum % 2 == 0:
        for i in range(0, n + 1, 2):
            result += power_of_two * combine(n, i)
            result %= mod
    else:
        for i in range(1, n + 1, 2):
            result += power_of_two * combine(n, i)
            result %= mod
    return result
  • Java
public class Solution {
    private static final int MOD = 1000000007;

    public int getMethod(ListNode head, String colors) {
        int[] fac = new int[110];
        int[] ifac = new int[110];
        fac[0] = 1;
        for (int i = 1; i < 105; i++) {
            fac[i] = (int)((long)fac[i - 1] * i % MOD);
        }
        ifac[104] = pow(fac[104], MOD - 2, MOD);
        for (int i = 103; i >= 0; i--) {
            ifac[i] = (int)((long)ifac[i + 1] * (i + 1) % MOD);
        }

        int oddCount = 0, evenCount = 0, currentSum = 0;
        ListNode node = head;
        int index = 0;
        while (node != null) {
            int value = node.val;
            char color = colors.charAt(index++);
            if (color == 'R') {
                currentSum += value;
            } else {
                if (value % 2 == 1) oddCount++;
                else evenCount++;
            }
            node = node.next;
        }

        int result = 0;
        int powerOfTwo = pow(2, evenCount, MOD);
        if (currentSum % 2 == 0) {
            for (int i = 0; i <= oddCount; i += 2) {
                result = (result + powerOfTwo * combine(oddCount, i, fac, ifac)) % MOD;
            }
        } else {
            for (int i = 1; i <= oddCount; i += 2) {
                result = (result + powerOfTwo * combine(oddCount, i, fac, ifac)) % MOD;
            }
        }
        return result;
    }

    private int pow(int base, int exp, int mod) {
        int result = 1;
        while (exp > 0) {
            if ((exp & 1) == 1) result = (int)((long)result * base % mod);
            base = (int)((long)base * base % mod);
            exp >>= 1;
        }
        return result;
    }

    private int combine(int n, int k, int[] fac, int[] ifac) {
        if (k > n || k < 0) return 0;
        return (int)((long)fac[n] * ifac[k] % MOD * ifac[n - k] % MOD);
    }
}
  • Cpp
#include <vector>
using namespace std;

class ListNode {
public:
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    int getMethod(ListNode* head, string colors) {
        const int MOD = 1000000007;
        vector<int> fac(110, 1), ifac(110, 1);
        for (int i = 1; i < 105; ++i) {
            fac[i] = (long long)fac[i - 1] * i % MOD;
        }
        ifac[104] = pow(fac[104], MOD - 2, MOD);
        for (int i = 103; i >= 0; --i) {
            ifac[i] = (long long)ifac[i + 1] * (i + 1) % MOD;
        }

        int oddCount = 0, evenCount = 0, currentSum = 0;
        while (head != nullptr) {
            int value = head->val;
            char color = colors[head->val - 1];
            if (color == 'R') {
                currentSum += value;
            } else {
                if (value % 2 == 1) oddCount++;
                else evenCount++;
            }
            head = head->next;
        }

        int result = 0;
        int powerOfTwo = pow(2, evenCount, MOD);
        if (currentSum % 2 == 0) {
            for (int i = 0; i <= oddCount; i += 2) {
                result = (result + powerOfTwo * combine(oddCount, i, fac, ifac)) % MOD;
            }
        } else {
            for (int i = 1; i <= oddCount; i += 2) {
                result = (result + powerOfTwo * combine(oddCount, i, fac, ifac)) % MOD;
            }
        }
        return result;
    }

private:
    int pow(int base, int exp, int mod) {
        int result = 1;
        while (exp > 0) {
            if (exp & 1) result = (long long)result * base % mod;
            base = (long long)base * base % mod;
            exp >>= 1;
        }
        return result;
    }

    int combine(int n, int k, const vector<int>& fac, const vector<int>& ifac) {
        if (k > n || k < 0) return 0;
        return (long long)fac[n] * ifac[k] % MOD * ifac[n - k] % MOD;
    }
};

📀 04.A先生的最小化调整

问题描述

A先生在处理一串由 ‘0’ 和 ‘1’ 组成的数据序列时,遇到了一个挑战。他需要通过最多 k k k 次操作将序列中的某些 ‘1’ 转变为 ‘0’,以此来缩短序列中连续 ‘1’ 的最长子串的长度。每次操作可以选择序列中的一个 ‘1’ 并将其变为 ‘0’。定义一个由连续 ‘1’ 组成的子串为合法子串。A先生希望找到一个方案,使得操作后合法子串的最大长度尽可能小。请计算这个最小的最大长度值。

输入格式

第一行包含一个字符串 s s s,表示数据序列。
第二行包含一个整数 k k k,表示最多操作次数。

输出格式

输出一个整数,表示经过最多 k k k 次操作后合法子串的最小最大长度。

样例输入

"101110110"
1

样例输出

2

数据范围

  • 字符串长度不超过 200000 200000 200000
  • 保证字符串由 ‘0’ 和 ‘1’ 两种字符组成。
  • 1 < k < 100000 1 < k < 100000 1<k<100000

题解

要解决这个问题,首先需要统计数据序列中所有合法子串的长度,并将它们存储起来。然后,通过二分查找确定最小的最大合法子串长度。在每次二分查找的过程中,我们尝试一个目标长度,并检查是否可以通过不超过 k k k 次操作达到这个目标。如果可以,我们尝试一个更小的长度;如果不可以,我们尝试一个更大的长度。最终,我们能找到一个长度,使得正好可以或者刚好无法通过 k k k 次操作达到这个长度,这个长度就是我们要找的答案。

参考代码

  • Python
def maxLen(s: str, k: int) -> int:
    counts = []
    count = 0
    for char in s:
        if char == '0':
            if count:
                counts.append(count)
            count = 0
        else:
            count += 1
    if count:
        counts.append(count)

    def check(mid) -> bool:
        operations = k
        for val in counts:
            left, right = 0, val + 1
            while left < right:
                cnt = (left + right) // 2
                if (cnt + 1) * mid >= val - cnt:
                    right = cnt
                else:
                    left = cnt + 1
            operations -= left
            if operations < 0:
                return False
        return True

    left, right = 0, len(s)
    while left < right:
        mid = (left + right) // 2
        if check(mid):
            right = mid
        else:
            left = mid + 1
    return left
  • Java
public class Solution {
    public int maxLen(String s, int k) {
        ArrayList<Integer> counts = new ArrayList<>();
        int count = 0;
        for (char ch : s.toCharArray()) {
            if (ch == '0') {
                if (count > 0) {
                    counts.add(count);
                }
                count = 0;
            } else {
                count++;
            }
        }
        if (count > 0) {
            counts.add(count);
        }

        int left = 0, right = s.length();
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (check(mid, counts, k)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }

    private boolean check(int mid, ArrayList<Integer> counts, int k) {
        int operations = k;
        for (int val : counts) {
            int left = 0, right = val + 1;
            while (left < right) {
                int cnt = (left + right) / 2;
                if ((cnt + 1) * mid >= val - cnt) {
                    right = cnt;
                } else {
                    left = cnt + 1;
                }
            }
            operations -= left;
            if (operations < 0) {
                return false;
            }
        }
        return true;
    }
}
  • Cpp
#include <vector>
#include <string>
using namespace std;

class Solution {
public:
    int maxLen(string s, int k) {
        vector<int> counts;
        int count = 0;
        for (char ch : s) {
            if (ch == '0') {
                if (count > 0) {
                    counts.push_back(count);
                }
                count = 0;
            } else {
                count++;
            }
        }
        if (count > 0) {
            counts.push_back(count);
        }

        int left = 0, right = s.length();
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (check(mid, counts, k)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }

private:
    bool check(int mid, const vector<int>& counts, int k) {
        int operations = k;
        for (int val : counts) {
            int left = 0, right = val + 1;
            while (left < right) {
                int cnt = (left + right) / 2;
                if ((cnt + 1) * mid >= val - cnt) {
                    right = cnt;
                } else {
                    left = cnt + 1;
                }
            }
            operations -= left;
            if (operations < 0) {
                return false;
            }
        }
        return true;
    }
};

写在最后

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取,会在飞书进行同步的跟新,5月1日之前限时免费提供ing~

在这里插入图片描述

  • 33
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
2023年3月11日,美团春季招聘笔试中共包含五道编程题目。以下是对每道题目的简要说明: 1. 题目一:这道题目要求解决一个数字统计的问题。可能涉及到的知识点包括数据结构、循环和条件判断等。解决问题的思路可能是使用字典等数据结构来保存统计结果,并使用循环逐个读取输入数据并进行统计。 2. 题目二:这道题目可能是一个字符串处理的问题。需要使用字符串的方法进行操作,如提取、拼接、查找和替换等。可能的解决思路包括使用正则表达式、切片和遍历等。 3. 题目:这道题目可能涉及到算法和数据结构的知识。可能是一道涉及到数组、链表、树等数据结构的问题。解决思路可能包括遍历、递归、搜索和排序等。 4. 题目四:这道题目可能是一个动态规划的问题。需要根据给定的条件和规则,通过动态规划的方式求解问题。解决思路包括定义状态和转移方程,使用递推或记忆化搜索进行求解。 5. 题目五:这道题目可能是一个图论或网络问题。需要根据给定的图或网络结构,解决一个相关的问题。可能涉及到广度优先搜索、深度优先搜索、最短路径等知识。解决思路可能包括使用图或网络的相关算法进行求解。 以上只是对这五道编程题目的一些可能情况进行的简要描述,具体的题目内容可能会有所不同。希望这些信息能对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值