美团2025年校招笔试真题手撕教程(二)

发布于:2025-05-27 ⋅ 阅读:(25) ⋅ 点赞:(0)

一、题目

小基定义以下三种单词是合法的:

  1. 所有字母都是小写。例如:good。
  2. 所有字母都是大写。例如:APP。
  3. 第一个字母大写,后面所有字母都是小写。例如:Alice。

现在小基拿到了一个单词,他每次操作可以修改任意一个字符的大小写。小基想知道最少操作几次可以使得单词变成合法的?

输入描述

一个仅由大写字母和小写字母组成的字符串,长度不超过 10510^5105。

输出描述

一个整数,代表操作的最小次数。

样例1

输入:

1

AbC

输出:

1

1

说明:变成 ABC 或者 Abc 均可。只需要 1 次操作。

二、分析

要解决小基提出的这个问题,我们需要计算将一个给定单词转换成三种合法形式之一所需的最少操作次数。合法形式包括全小写、全大写以及首字母大写其余字母小写。每次操作允许改变任意一个字符的大小写。

首先,我们需要遍历整个单词并统计每种合法形式所需的操作次数。

对于全小写形式,我们需要统计所有大写字母的数量,因为每个大写字母都需要转换为小写。

对于全大写形式,我们需要统计所有小写字母的数量,因为每个小写字母都需要转换为大写。

对于首字母大写其余小写的合法形式,我们需要单独考虑首字母和其他字母。首字母如果是小写,需要转换为大写,这算一次操作。对于其余字母,统计所有大写字母的数量,因为这些字母需要转换为小写。

在计算完这三种合法形式所需的操作次数后,我们找到其中的最小值,这就是将单词转换为合法形式所需的最少操作次数。

举个例子,假设输入的单词是 “AbC”,我们需要计算三种合法形式所需的操作次数:

全小写形式需要将首字母 ‘A’ 转换为小写,以及将第三个字母 ‘C’ 转换为小写,共需要两次操作。

全大写形式需要将第二个字母 ‘b’ 转换为大写,以及将第三个字母 ‘C’ 转换为大写,共需要两次操作。

首字母大写其余小写形式中,首字母已经是大写,无需转换。第三个字母 ‘C’ 需要转换为小写,所以只需要一次操作。因此,在三种合法形式中,最少操作次数是一次。这就是我们需要输出的结果。

三、代码

这段代码实现了计算将给定单词转换为合法形式所需的最少操作次数的功能。首先,它读取输入的单词并初始化三个变量,分别用于记录将单词转换为全小写、全大写以及首字母大写其余小写三种合法形式所需的操作次数。

# 读取输入
word = input().strip()

# 初始化三种合法形式所需的操作次数
all_lower = 0
all_upper = 0
first_upper_rest_lower = 0

# 遍历每个字符并统计操作次数
for i, char in enumerate(word):
    if i == 0:
        # 首字符
        if char.islower():
            all_upper += 1  # 如果首字符是小写,全大写形式需要改变它
            first_upper_rest_lower += 1  # 首字母大写形式需要改变它
        else:
            all_lower += 1  # 如果首字符是大写,全小写形式需要改变它
    else:
        # 非首字符
        if char.islower():
            all_upper += 1  # 全大写形式需要改变它
            first_upper_rest_lower += 0  # 首字母大写形式不需要改变它
        else:
            all_lower += 1  # 全小写形式需要改变它
            first_upper_rest_lower += 1  # 首字母大写形式需要改变它

# 计算最小操作次数并输出
print(min(all_lower, all_upper, first_upper_rest_lower))

然后,代码遍历单词中的每个字符。对于首字符,如果它是小写,那么转换为全大写和首字母大写形式都需要改变它,所以对应的计数器加一;如果它是大写,转换为全小写形式需要改变它,对应的计数器加一。对于非首字符,如果是小写,转换为全大写形式需要改变它,对应的计数器加一;如果是大写,转换为全小写和首字母大写形式需要改变它,对应的计数器加一。

最后,代码通过比较三种合法形式所需的操作次数,找出最小值并输出。这种算法能够高效地解决问题,因为只需一次遍历单词即可统计所有必要的信息,时间复杂度为O(n),其中n是单词的长度,适合处理长度较大的输入。

四、发散

在解决小基的问题时,我们主要采用了直接遍历和统计的算法,这种方法简单直接,能够高效地解决问题。在算法领域,这种基于遍历和统计的方法属于基础的线性扫描算法,适用于处理一系列元素并进行简单的统计操作。

当面对更复杂的问题时,我们可以考虑其他算法策略。例如,动态规划是一种通过将复杂问题分解为更小子问题来求解的方法,适用于具有重叠子问题和最优子结构特征的问题。在本题中,虽然直接遍历已经足够高效,但如果问题扩展为需要考虑更多状态或操作步骤,动态规划可能成为一种选择。

另一个值得思考的方向是贪心算法。贪心算法在每一步选择中都采取当前状态下最优的选择,从而希望导致全局最优解。在本题中,我们通过直接统计三种合法形式所需的操作次数并选择最小值,这本身可以看作是一种贪心策略。在更复杂的问题中,贪心算法需要仔细验证其正确性,以确保每一步的局部最优选择能够带来全局最优解。

此外,分治算法也是一种重要的算法思想。它将问题分解为多个子问题,分别求解子问题,然后合并子问题的解来得到原问题的解。在本题中,分治算法可能不太适用,但在处理更复杂的数据结构或需要并行处理的问题时,分治算法能够发挥巨大的优势。

在算法学习的进阶过程中,我们还可以探索诸如图论算法、字符串匹配算法、机器学习算法等领域。这些算法在特定的问题中能提供高效的解决方案。通过对不同算法的深入研究和实践,我们能不断提升自己解决问题的能力,找到更高效、更优雅的解决方案。


网站公告

今日签到

点亮在社区的每一天
去签到