LeetCode in Kotlin

2227. Encrypt and Decrypt Strings

Hard

You are given a character array keys containing unique characters and a string array values containing strings of length 2. You are also given another string array dictionary that contains all permitted original strings after decryption. You should implement a data structure that can encrypt or decrypt a 0-indexed string.

A string is encrypted with the following process:

  1. For each character c in the string, we find the index i satisfying keys[i] == c in keys.
  2. Replace c with values[i] in the string.

Note that in case a character of the string is not present in keys, the encryption process cannot be carried out, and an empty string "" is returned.

A string is decrypted with the following process:

  1. For each substring s of length 2 occurring at an even index in the string, we find an i such that values[i] == s. If there are multiple valid i, we choose any one of them. This means a string could have multiple possible strings it can decrypt to.
  2. Replace s with keys[i] in the string.

Implement the Encrypter class:

Example 1:

Input [“Encrypter”, “encrypt”, “decrypt”] [[[‘a’, ‘b’, ‘c’, ‘d’], [“ei”, “zf”, “ei”, “am”], [“abcd”, “acbd”, “adbc”, “badc”, “dacb”, “cadb”, “cbda”, “abad”]], [“abcd”], [“eizfeiam”]]

Output: [null, “eizfeiam”, 2]

Explanation: Encrypter encrypter = new Encrypter([[‘a’, ‘b’, ‘c’, ‘d’], [“ei”, “zf”, “ei”, “am”], [“abcd”, “acbd”, “adbc”, “badc”, “dacb”, “cadb”, “cbda”, “abad”]);

encrypter.encrypt(“abcd”); // return “eizfeiam”. // ‘a’ maps to “ei”, ‘b’ maps to “zf”, ‘c’ maps to “ei”, and ‘d’ maps to “am”.

encrypter.decrypt(“eizfeiam”); // return 2. // “ei” can map to ‘a’ or ‘c’, “zf” maps to ‘b’, and “am” maps to ‘d’. // Thus, the possible strings after decryption are “abad”, “cbad”, “abcd”, and “cbcd”. // 2 of those strings, “abad” and “abcd”, appear in dictionary, so the answer is 2.

Constraints:

Solution

class Encrypter(keys: CharArray, values: Array<String>, dictionary: Array<String>) {
    private val eMap: MutableMap<Char, String>
    private val dMap: MutableMap<String, Int>

    init {
        eMap = HashMap()
        dMap = HashMap()
        for (i in keys.indices) {
            eMap[keys[i]] = values[i]
        }
        for (s in dictionary) {
            val str = encrypt(s)
            if (str != "" && str != "null") {
                dMap[str] = dMap.getOrDefault(str, 0) + 1
            }
        }
    }

    fun encrypt(word1: String): String {
        val sb = StringBuilder()
        for (c in word1.toCharArray()) {
            sb.append(eMap[c])
        }
        return sb.toString()
    }

    fun decrypt(word2: String): Int {
        return dMap.getOrDefault(word2, 0)
    }
}
/*
 * Your Encrypter object will be instantiated and called as such:
 * var obj = Encrypter(keys, values, dictionary)
 * var param_1 = obj.encrypt(word1)
 * var param_2 = obj.decrypt(word2)
 */