Task1 Letter Occurrences

Task 1

You are given a string letters made of N English letters. Count the number of different letters that appear in both uppercase and lowercase where all lowercase occurrences of the given letter appear before any uppercase occurrence.
For example, for letters = “aaAbcCABBc” the answer is 2. The condition is met for letters ‘a’ and ‘b’, but not for ‘c’.
Write a function:

class Solution {    public int solution(String letters);    }**

that, given a string letters, returns the number of different letters fulfilling the conditions above.

Examples:

  1. Given letters = ''aaAbcCABBc", the function should return 2, as explained above.
  2. Given letters = “xyzXYZabcABC”, the function should return 6.
  3. Given letters = “ABCabcAefG”, the function should return 0.

Write an efficient algorithm for the following assumptions:

  • N is an integer within the range [1…100,000];
  • string letters is made only of letters (a-z and/or A-Z).

思路 1

  • 初始化 int 数组为 0, length = 26,分别对应A-Z 26位字母;
  • 遍历字符串
  • 如果当前为 -1,continue
  • 如果遇到小写字母,且当前为0,则置为 1
  • 如果遇到小写字母,且当前为1,则 continue
  • 如果遇到小写字母,且当前为2,则置为 -1
  • 如果遇到大写字母,且当前为0,则置为 -1
  • 如果遇到大写字母,且当前为 1,则置为 2
  • 如果遇到大写字母,且当前位为 2,则continue
  • 遍历结束
  • 统计数组中为 2 的个数并返回

复杂度

时间复杂度:O(n), n <= 10^5
空间复杂度:O(1)

Code

public int matchedLettersCount(String letters) {
        int count = 0;
        int[] array = new int[26];
        for (int i = 0; i < letters.length(); i++) {
            if (Character.isLowerCase(letters.charAt(i))) { // lower
                int index = letters.charAt(i) - 'a';
                // -1, 1 do nothing
                if (array[index] == 0)
                    array[index] = 1;
                if (array[index] == 2)
                    array[index] = -1;
            } else { // upper
                int index = Character.toLowerCase(letters.charAt(i)) - 'a';
                // -1, 2 do nothing
                if (array[index] == 0)
                    array[index] = -1;
                else if (array[index] == 1)
                    array[index] = 2;
            }
        }

        for (int e : array) {
            if (e == 2)
                count++;
        }
        return count;
    }

思路 2

  • 使用1个set来记录不符合条件的小写字母 failedLetters, 1个set来记录符合条件的大小写字母 candidateLetters
  • 遍历字符串
  • 如果是小写字母char,failedLetters不存在,candidateLetters不存在,则认为第一次遇到,将小写字母加入候选组
  • 如果是小写字母char,failedLetters不存在,但candidateLetters存在其大写字母,则视为失败,失败组加入该小写字母,候选组删除对应的大写字母
  • 如果是大写字母char,candidateLetters 存在其小写字母,认为当前符合条件,将大写字母加入候选组
  • 如果是大写字母char,candidateLetters 不存在其小写字母,认为失败,将其对应的小写字母加入失败组
  • 遍历结束
  • 最后统计candidateLetters中大写字母的个数并返回

复杂度

时间复杂度:O(n)
空间复杂度:O(1)

Code

    public int solutionSet(String letters) {
        Set candidateLetters = new HashSet<>();
        Set failedLetters = new HashSet<>();
        int count = 0;
        for (char letter : letters.toCharArray()) {
            if (Character.isLowerCase(letter) && !candidateLetters.contains(letter) && !failedLetters.contains(letter))
                candidateLetters.add(letter);
            if (Character.isLowerCase(letter) && candidateLetters.contains(Character.toUpperCase(letter)) && !failedLetters.contains(letter)) {
                failedLetters.add(letter);
                candidateLetters.remove(Character.toUpperCase(letter));
            }
            if (Character.isUpperCase(letter)) {
                if (candidateLetters.contains(Character.toLowerCase(letter)))
                    candidateLetters.add(letter);
                else
                    failedLetters.add(Character.toLowerCase(letter));
            }
        }
        for (Character letter : candidateLetters) {
            if (Character.isUpperCase(letter))
                count++;
        }
        return count;
    }

你可能感兴趣的:(算法)