给你一个下标从 0 开始的字符串 s ,该字符串由用户输入。按键变更的定义是:使用与上次使用的按键不同的键。例如 s = “ab” 表示按键变更一次,而 s = “bBBb” 不存在按键变更。
返回用户输入过程中按键变更的次数。
注意:shift 或 caps 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 仅由英文大写字母和小写字母组成。
法一:直接模拟,要点在于,由于大写字母的ASCII码比小写字母的ASCII码小,因此可根据当前遍历到的字符与A的差值与25的大小比较而得知是大写还是小写:
class Solution {
public:int countKeyChanges(string s) {int ans = 0;int lastDiff = (s[0] - 'A') > 25 ? (s[0] - 'a') : (s[0] - 'A');for (char c : s){int cdiff = (c - 'A') > 25 ? (c - 'a') : (c - 'A');ans += cdiff != lastDiff; lastDiff = cdiff;}return ans;}
};
如果s的长度为n,此算法时间复杂度为O(n),空间复杂度为O(1)。
法二:利用大小写字母的ASCII码的后5位相同:
class Solution {
public:int countKeyChanges(string s) {int ans = 0;for (int i = 1; i < s.size(); ++i){ans += (s[i] & 31) != (s[i - 1] & 31);// ans += (s[i] & 0b11111) != (s[i - 1] & 0b11111);}return ans;}
};
如果s的长度为n,此算法时间复杂度为O(n),空间复杂度为O(1)。