【一天一大 lee】单词规律 (难度:简单) - Day20201216

20201216

题目:

给定一种规律 pattern  和一个字符串  str ,判断 str 是否遵循相同的规律。

这里的   遵循   指完全匹配,例如, pattern  里的每个字母和字符串  str  中的每个非空单词之间存在着双向连接的对应规律。

示例:

  1. 示例 1:
输入: pattern = "abba", str = "dog cat cat dog"
输出: true
  1. 示例 2:
输入:pattern = "abba", str = "dog cat cat fish"
输出: false
  1. 示例 3:
输入: pattern = "aaaa", str = "dog cat cat dog"
输出: false
  1. 示例 4:
输入: pattern = "abba", str = "dog dog dog dog"
输出: false

说明:

  • 你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。

抛砖引玉

有点像说出 AABC、AABB 模式成语的味道了…

看到题会觉得,恩,确实是简单的题,匹配每个模式字符的位置就好了,再仔细一想,恩? 不对,这 TM 是简单的题?

要怎么模式串转换成声明格式才能方便 s 去匹配呢,先想到的一定是哈希方法:

如果哈希记录每个模式字符的位置,但是缺少了模式字符与 s 中元素的对应关系,那么只能使用哈希记录模式串与 s 单个元素的对应关系,且对应关系是双向的。

  • 声明两个哈希表
  • 遍历 list&pattern,同时更新两个哈希表的映射关系
  • 遇到映射关系冲突(pattern 某个字符对应 list 中元素,而 list 中元素不对应该字符)时返回 false

抛砖引玉

/**
 * @param {string} pattern
 * @param {string} s
 * @return {boolean}
 */
var wordPattern = function(pattern, s) {
    const list = s.split(' ')
    // 长度不匹配
    if (list.length !== pattern.length) return false
    let pMs = new Map(),
        sMp = new Map(),
        index = 0
    while (index < list.length) {
        const pStr = pattern[index],
            sStr = list[index]
        // 双向对应关系冲突
        if (
            (pMs.has(pStr) && pMs.get(pStr) !== sStr) ||
            (sMp.has(sStr) && sMp.get(sStr) !== pStr)
        ) {
            return false
        }
        pMs.set(pStr, sStr)
        sMp.set(sStr, pStr)
        index++
    }
    return true
}

使用 indexOf 标记映射

将每个元素第一次出现的位置作为元素的标记,
遍历 list&pattern:

  • 如果模式字符和 s 的元素匹配,那么他们分别在 list 和 pattern 第一次出现的位置相同
  • 如果他们不匹配(pattern 字符对应的 s 元素变化了),那么他们分别在 list 和 pattern 第一次出现的位置也会不同
var wordPattern = function(pattern, s) {
    const list = s.split(' ')
    // 长度不匹配
    if (list.length !== pattern.length) return false
    let index = 0
    while (index < list.length) {
        const pStr = pattern[index],
            sStr = list[index]
        if (pattern.indexOf(pStr) != list.indexOf(sStr)) return false
        index++
    }
    return true
}

博客: 前端小书童

每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目
欢迎关注留言

公众号:前端小书童

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值