首页 > 腾讯音乐TME 20220908笔试题解
头像
王悟空
编辑于 2022-09-09 10:37 河北
+ 关注

腾讯音乐TME 20220908笔试题解

T1

给定一个只包含小写字母字符串,每次可以选择两个相同的字符删除,并在字符串结尾新增任意一个小写字母。
请问最少多少次操作后,所有的字母都不相同?

字符串长度<1e3

input:
abab

output:
2

第一次把2个a变成f,第二次把2个b变成b。得到fb,每个字母都不相同,最少操作次数为2。

贪心就行了,每次把选2个字母变成当前出现次数最少的字母。因为字符串长度就1000,最多进行999次操作,每次操作遍历所有字母找出现次数最小的就可以。总体复杂度O(26n)

顺便做个follow-up,如果把字符串长度拉到1e5呢?其实可以以O(n)的解法来解。先考虑会消除多少次,对于某个字母出现m次,那么这个字母要操作m/2次使其变成0、1,同时产出m/2个字符,我们先把这产出的放到一边不考虑,先遍历所有字母,查看会产出多少字符。

得到产出字符数之后,可以遍历剩余的字母,根据上面所述,一个字母最终会剩下0/1,如果一个字母剩下0个,说明操作途中其他产出的字母就可以放到这个位置,不需要额外操作。否则产出的字符仍然需要额外操作。

考虑a~y每个字母都出现3次,z不出现。一共可以产出25个字母(a~y每个产出1个),同时a~y剩余1个,z剩余0个。那么因为有一个剩余0个的,前面在任意字母操作的时候,就可以直接往z这里放一个。这样还剩下24个产出,这产出的字母,每一个字母都需要额外操作一次,所以拢共需要操作24+25=49次。

class Solution:
    def minOperations(self, str: str) -> int:
        c = [0] * 26
        for i in str: c[ord(i) - ord('a')] += 1

        ans = 0
        more = 0
        for i in range(26):
            ans += c[i] // 2
            more += c[i] // 2
            c[i] %= 2
        for i in range(26):
            if c[i] == 0 and more:
                c[i] += 1
                more -= 1
        ans += more

        return ans

T2

题目描述
已知一个二叉树的先序遍历序列和中序遍历序列,但其中一些节点的值可能相同。
请你返回所有满足条件的二叉树。二叉树在数组中的顺序是任意的。

input: 
[1,1,2],[1,2,1]

output:
[{1,1,#,#,2},{1,#,1,2}]

case中会产出以下2个树:

图片说明

图片说明

经典递归。只需要枚举在中序遍历序列中每个可能成为下一个根节点的节点即可。因为是枚举的中序序列,那么假设某一个节点为根节点,这个节点左侧所有节点均为它的左子树,递归处理即可。

class Solution:
    def getBinaryTrees(self, preOrder: List[int], inOrder: List[int]) -> List[TreeNode]:
        if not preOrder: return [None]
        ans = []
        n = len(preOrder)

        for i in range(n):
            if inOrder[i] == preOrder[0]:
                for l in self.getBinaryTrees(preOrder[1:i + 1], inOrder[:i]):
                    for r in self.getBinaryTrees(preOrder[i + 1:], inOrder[i + 1:]):
                        node = TreeNode(preOrder[0])
                        node.left = l
                        node.right = r
                        ans.append(node)

        return ans

T3

给定一棵二叉树,二叉树的每个结点只有0或2个孩子。
你需要对每个结点赋值一个正整数,使得每个结点的左右子树权值和相等。
你需要返回所有结点的最小权值和对1e9+7取模的结果。
二叉树结点个数不超过1e5。

input:
{0,0,0}

output:
3

题目case如图:
图片说明

正常递归,因为两侧值相等,每次把左右子树小的值设置成大的值即可,然后本节点最小赋值为1。

不知道需不需要处理大数,反正Python不需要,其他语言可能需要注意一下long吧。

class Solution:
    def getTreeSum(self, tree: TreeNode) -> int:
        def f(node):
            return 0 if not node else max(f(node.left), f(node.right)) * 2 + 1

        return f(tree) % 1000000007

全部评论

(15) 回帖
加载中...
话题 回帖