刷题的日常-解密消息

96 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

新年的第一篇水文

刷题的日常-2023年2月1号

一天一题,保持脑子清爽

解密消息

来自leetcode的 2325 题,题意如下:

给你字符串 key 和 message ,分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下:

1、使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。</br>
2、将替换表与普通英文字母表对齐,形成对照表。</br>
3、按照对照表 替换 message 中的每个字母。</br>
4、空格 ' ' 保持不变。</br>
  • 例如,key = "happy boy"(实际的加密密钥会包含字母表中每个字母 至少一次),据此,可以得到部分对照表('h' -> 'a'、'a' -> 'b'、'p' -> 'c'、'y' -> 'd'、'b' -> 'e'、'o' -> 'f')。

返回解密后的消息。

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出两个字符串
    • 一个是key,代表映射关系
    • 一个是message,代表需要通过映射关系来求解的字符串
  • 要求我们将key中第一次出现的字符作为新的映射关系,将message中的字符进行替换
  • 题目保证26个字母都有映射关系
  • 要求我们返回解密后的字符串

做题思路

根据题目的描述,我们可以构建对应的映射关系之后进行替换即可,步骤如下:

  • 开辟一个数组作为最终替换结果
  • 开辟一个布尔数组保存是否出现过记录
  • 再开辟一个数组用来保存映射关系
  • 循环填入数组里的每个字符
  • 需要注意的是,key 和 message中都存在 空格,所以需要进行特殊判断
  • 最终将message中的字母进行映射即可

代码实现

代码实现如下:

public class Solution {
    public String decodeMessage(String key, String message) {
        char[] res = new char[message.length()];
        boolean[] appearMap = new boolean[26];
        char[] charMap = new char[26];
        int idx = 0, c;
        for (int i = 0; i < charMap.length; i++) {
            while ((c = key.charAt(idx++) - 'a') < 0 || appearMap[c]) {}
            charMap[c] += i + 'a';
            appearMap[c] = true;
        }
        for (int i = 0; i < message.length(); i++) {
            c = message.charAt(i);
            if (c == ' ') {
                res[i] = ' ';
                continue;
            }
            res[i] = charMap[c - 'a'];
        }
        return new String(res);
    }
}

a88680f4dfffd1b0d92c7e476af812e.png