刷题的日常-查找和替换模式

109 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

刷题的日常

一天一题,保持脑子清爽

查找和替换模式

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

你有一个单词列表words和一个模式pattern,你想知道 words 中的哪些单词与模式匹配。
如果存在字母的排列 p,使得将模式中的每个字母 x 替换为 p(x) 之后,我们就得到了所需的单词,那么单词与模式是匹配的。
(回想一下,字母的排列是从字母到字母的双射:每个字母映射到另一个字母,没有两个字母映射到同一个字母。)
返回 words 中与给定模式匹配的单词列表。
你可以按任何顺序返回答案。 来个示例:

输入:words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
输出:["mee","aqq"]
解释:
"mee" 与模式匹配,因为存在排列 {a -> m, b -> e, ...}。
"ccc" 与模式不匹配,因为 {a -> c, b -> c, ...} 不是排列。
因为 ab 映射到同一个字母。

理解题意

有点类似与正则匹配

  • pattern的字符可以映射为任意其它字符
  • 已经被映射过的不能重新映射
  • 数量必须要一致

做题思路

其实很简单

  • 开辟个Hash表保存pattern的映射关系
  • 已经映射的字符不能重复映射,所以我们需要再开辟个Hash表保存已经映射过的pattern字符
  • 遍历words数组
    • 如果字符串长度不相等,则不能映射
    • 如果映射没有重复,并且符合pattern的规则,这添加进结果集
  • 返回结果列表

代码实现

需要遍历数组,并且校验字符串,假设字符串最大长度为m,words的长度为n,则复杂度为O(m * n),代码如下:

public class Solution {
    public List<String> findAndReplacePattern(String[] words, String pattern) {
        List<String> result = new LinkedList<>();
        Map<Character, Character> map = new HashMap<>(pattern.length());
        Map<Character, Character> reMap = new HashMap<>(pattern.length());
        for (String word : words) {
            if (checkPattern(word, pattern, map, reMap)) {
                result.add(word);
            }
        }

        return result;
    }
    private boolean checkPattern(String word, String pattern, Map<Character, Character> map, Map<Character, Character> reMap) {
        if (word.length() != pattern.length()) {
            return false;
        }
        map.clear();
        reMap.clear();
        for (int i = 0; i < pattern.length(); i++) {
            char pC = pattern.charAt(i);
            char wC = word.charAt(i);
            Character mC = map.get(pC);
            if (mC != null && mC != wC) {
                return false;
            }
            Character c = reMap.get(wC);
            if (c != null && c != pC) {
                return false;
            }
            map.put(pC, wC);
            reMap.put(wC, pC);
        }
        return true;
    }
}

image.png