Problem

You are given a 0-indexed string s typed by a user. Changing a key is defined as using a key different from the last used key. For example, s = "ab" has a change of a key while s = "bBBb" does not have any.

Return the number of times the user had to change the key.

Note: Modifiers like shift or caps lock won’t be counted in changing the key that is if a user typed the letter 'a' and then the letter 'A' then it will not be considered as a changing of key.

Examples

Example 1

1
2
3
4
5
6
7
8
Input: s = "aAbBcC"
Output: 2
Explanation: 
From s[0] = 'a' to s[1] = 'A', there is no change of key as caps lock or shift is not counted.
From s[1] = 'A' to s[2] = 'b', there is a change of key.
From s[2] = 'b' to s[3] = 'B', there is no change of key as caps lock or shift is not counted.
From s[3] = 'B' to s[4] = 'c', there is a change of key.
From s[4] = 'c' to s[5] = 'C', there is no change of key as caps lock or shift is not counted.

Example 2

1
2
3
Input: s = "AaAaAaaA"
Output: 0
Explanation: There is no change of key since only the letters 'a' and 'A' are pressed which does not require change of key.

Constraints

  • 1 <= s.length <= 100
  • s consists of only upper case and lower case English letters.

Solution

Method 1 – Compare Lowercase Keys

Intuition

A key change occurs when the lowercase of the current character differs from the previous. Ignore case (shift/caps lock).

Approach

  1. Iterate through the string, compare lowercase of current and previous character.
  2. Increment count if they differ.
  3. Return the total count.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <string>
using namespace std;
class Solution {
public:
    int countChangingKeys(string s) {
        int cnt = 0;
        for (int i = 1; i < s.size(); ++i)
            if (tolower(s[i]) != tolower(s[i-1])) ++cnt;
        return cnt;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import "strings"
func countChangingKeys(s string) int {
    cnt := 0
    for i := 1; i < len(s); i++ {
        if strings.ToLower(string(s[i])) != strings.ToLower(string(s[i-1])) {
            cnt++
        }
    }
    return cnt
}
1
2
3
4
5
6
7
8
class Solution {
    public int countChangingKeys(String s) {
        int cnt = 0;
        for (int i = 1; i < s.length(); ++i)
            if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(i-1))) cnt++;
        return cnt;
    }
}
1
2
3
4
5
6
7
8
class Solution {
    fun countChangingKeys(s: String): Int {
        var cnt = 0
        for (i in 1 until s.length)
            if (s[i].lowercaseChar() != s[i-1].lowercaseChar()) cnt++
        return cnt
    }
}
1
2
3
class Solution:
    def countChangingKeys(self, s: str) -> int:
        return sum(s[i].lower() != s[i-1].lower() for i in range(1, len(s)))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
impl Solution {
    pub fn count_changing_keys(s: String) -> i32 {
        let bytes = s.as_bytes();
        let mut cnt = 0;
        for i in 1..bytes.len() {
            if bytes[i].to_ascii_lowercase() != bytes[i-1].to_ascii_lowercase() { cnt += 1; }
        }
        cnt
    }
}
1
2
3
4
5
6
function countChangingKeys(s: string): number {
    let cnt = 0;
    for (let i = 1; i < s.length; ++i)
        if (s[i].toLowerCase() !== s[i-1].toLowerCase()) cnt++;
    return cnt;
}

Complexity

  • ⏰ Time complexity: O(n)
  • 🧺 Space complexity: O(1)