笔试真题230504

腾讯音乐娱乐集团2023校园招聘技术类岗位编程题合集

1. 字符串操作

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M

示例1

输入例子:
"abab"
输出例子:
2
例子说明:
第一次操作将两个'a'变成一个'f',字符串变成"bbf"。
第二次操作将两个'b'变成一个'b',字符串变成"fb"。
操作方式不是唯一的,但可以证明,最少操作次数为2。

这是一个经典的字符串问题,可以通过使用贪心算法来解决。首先,我们可以将相同的字母成对删除,直到所有的字母都不重复为止。

具体做法如下:

  1. 统计每个字母在字符串中出现的次数,如果某个字母出现了偶数次,则可以将其全部删除。
  2. 如果存在一个字母出现了奇数次,那么只能 保留其中一个,剩余的字母仍然需要 删除。在这种情况下,我们可以将这个字母的偶数部分和其他的偶数字母一起删除,然后在字符串结尾 b保留一个小写字母,使得新的字符串中该字母出现次数为 1。

因此,总的操作次数为奇数字母的数量减一加上剩余偶数字母的数量的和除以二,即:

(count_odd - 1 + count_even) / 2

其中,count_odd 是奇数字母的数量,count_even 是偶数字母的数量。

以上就是输入用例较小时最少的操作次数。下面讨论输入用例较大时的情况。

因为题目给出的字符串只包含小写字母,所以新字符串长度最长为26。如果经过以上操作得到的字符串长度大于或等于26,那么还需要进行操作。可以将第一次操作得到的字符串分为两个子串:操作后的偶数串和奇数串,长度分别为count_even / 2count_odd,其中奇数串一定不含相同字符且长度小于26.

做如下操作:

1.对偶数串重复操作直到只剩a~z。根据题设可知每次操作是删除两个字符增加一个字符,那么每次操作后的字符串长度减一
2.删除第1步操作后的字符串和奇数串中相同的字符

因此,总的操作次数为偶数字母的数量除以二减二十六加上剩余奇数字母的数量,即:

count_event - 26 + count_ood

可以使用Java实现上面提到的贪心算法来解决这个问题。以下是一个可能的实现:

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回满足题意的最小操作数
     * @param str string字符串 给定字符串
     * @return int整型
     */
    public int minOperations (String str) {
        // write code here
        Map<Character, Integer> count = new HashMap<>();
        for (char c : str.toCharArray()) {
            count.put(c, count.getOrDefault(c, 0) + 1);
        }
        int oddCount = 0;
        int evenCount = 0;
        for (int c : count.values()) {
            if (c % 2 == 0) {
                evenCount += c;
            } else {
                oddCount++;
                evenCount += c - 1;
            }
        }
        int ans = evenCount / 2;
        if (ans >= 26) {
            ans += evenCount / 2 - 26 + oddCount ;
        }
        return ans;
    }
}

首先,我们使用一个 Map 来统计每个字母在字符串中出现的次数。然后,我们遍历所有的统计值,将偶数字母的数量加入到 evenCount 变量中,将奇数字母的数量加入到 oddCount 变量中,并且对于每个奇数字母,减去一个,使其成为偶数字母。最后,我们将操作次数作为ans的结果返回。

请注意,在代码中使用了 Java 8 的流式编程风格来更简便地统计字符出现次数。如果不熟悉这种语言特性,也可以使用传统的循环方式来实现。

2.带重复节点的前序中序二叉树

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M

示例1

输入例子:
[1,1,2],[1,2,1]
输出例子:
[{1,1,#,#,2},{1,#,1,2}]
例子说明:

请添加图片描述

请添加图片描述

上图的两个二叉树都满足前序遍历为[1,1,2],中序遍历为[1,2,1]
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param preOrder int整型ArrayList 
     * @param inOrder int整型ArrayList 
     * @return TreeNode类ArrayList
     */
    public ArrayList<TreeNode> getBinaryTrees (ArrayList<Integer> preOrder, ArrayList<Integer> inOrder) {
        // write code here
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dongxuluo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值