按键变更的次数

标签: 字符串

难度: Easy

给你一个下标从 0 开始的字符串 s ,该字符串由用户输入。按键变更的定义是:使用与上次使用的按键不同的键。例如 s = "ab" 表示按键变更一次,而 s = "bBBb" 不存在按键变更。

返回用户输入过程中按键变更的次数。

注意:shiftcaps lock 等修饰键不计入按键变更,也就是说,如果用户先输入字母 'a' 然后输入字母 'A' ,不算作按键变更。

示例 1:

输入:s = "aAbBcC"
输出:2
解释: 
从 s[0] = 'a' 到 s[1] = 'A',不存在按键变更,因为不计入 caps lock 或 shift 。
从 s[1] = 'A' 到 s[2] = 'b',按键变更。
从 s[2] = 'b' 到 s[3] = 'B',不存在按键变更,因为不计入 caps lock 或 shift 。
从 s[3] = 'B' 到 s[4] = 'c',按键变更。
从 s[4] = 'c' 到 s[5] = 'C',不存在按键变更,因为不计入 caps lock 或 shift 。

示例 2:

输入:s = "AaAaAaaA"
输出:0
解释: 不存在按键变更,因为这个过程中只按下字母 'a' 和 'A' ,不需要进行按键变更。

提示:

  • 1 <= s.length <= 100
  • s 仅由英文大写字母和小写字母组成。

Submission

运行时间: 19 ms

内存: 16.1 MB

class Solution:
    def countKeyChanges(self, s: str) -> int:
        answer = 0 
        pre_code = ord(s[0])
        for letter in s[1:]:     # 不同的按键满足的条件:码值不相等并且差距不等于32
            if abs(ord(letter) - pre_code) != 32 and ord(letter) - pre_code:
                answer += 1 
            pre_code = ord(letter)
        return answer

Explain

此题解的核心思路是遍历字符串中的每个字符,并比较当前字符与前一个字符的ASCII码值差异。如果ASCII码值之间的差异不是32(即大小写字母之间的差异),并且两个字符不完全相同,则认为发生了按键变更。首先,初始化答案计数为0,并记录第一个字符的ASCII码值。然后,从第二个字符开始,比较每一个字符与前一个字符的ASCII码值。如果两个字符的ASCII码值之差不等于32且不为0(即字符不相同,且不是大小写变换),则按键变更计数加一。更新前一个字符的ASCII码值为当前字符的ASCII码值,继续下一轮比较,直到字符串遍历结束。

时间复杂度: O(n)

空间复杂度: O(1)

# 定义解决方案类

class Solution:
    def countKeyChanges(self, s: str) -> int:
        answer = 0  # 初始化按键变更次数为0
        pre_code = ord(s[0])  # 记录第一个字符的ASCII码值
        for letter in s[1:]:  # 遍历字符串从第二个字符开始
            # 判断当前字符与前一个字符是否为大小写变体或不同字符
            if abs(ord(letter) - pre_code) != 32 and ord(letter) - pre_code:
                answer += 1  # 如果是不同按键,增加按键变更计数
            pre_code = ord(letter)  # 更新前一个字符的ASCII码值为当前字符
        return answer  # 返回总的按键变更次数

Explore

使用ASCII码值之间的差异来判断按键是否变更可以同时处理字符相同和字符为大小写变体的情况。直接比较字符是否相同会忽略大小写字母之间的关系,即使它们在键盘上由同一个按键产生。因此,通过ASCII码值的差异,我们能更细致地区分是否需要按键变更,例如从'a'到'A'或从'A'到'a',虽然需要Caps Lock的变更,但实际上是同一个按键的两种输出。

在ASCII编码中,大小写字母之间的差异正好是32(例如,'A'的ASCII码为65,而'a'的ASCII码为97)。这一逻辑依据ASCII码的这一特性来判断字符是否为大小写变体。然而,这一逻辑仅适用于遵循类似编码结构的环境,如ASCII或兼容ASCII的Unicode。在不遵循此结构的编码系统中(例如,某些多字节字符编码),这一逻辑可能不适用。

这两个条件共同确保字符既不是完全相同的,也不是仅仅由大小写差异的字符。第一个条件`abs(ord(letter) - pre_code) != 32`确保两个字符不是简单的大小写变体(即不是仅通过Caps Lock键就可以实现的变化)。第二个条件`ord(letter) - pre_code`确保字符不完全相同(即ASCII码值不相等)。这两个条件结合使用可以准确地判断何时需要按键变更,排除了相同字符和大小写变体的情况,这些情况在某些情形下可能不需要实际的按键变更。