首页 > 编程语言 >算法编程中的Word 四兄弟 Word Break , Word Ladder, Word Search, Word Pattern

算法编程中的Word 四兄弟 Word Break , Word Ladder, Word Search, Word Pattern

时间:2023-07-28 23:08:14浏览次数:40  
标签:distance Search Word Pattern self end return start word

Word 四兄弟 Word Break , Word Ladder, Word Search, Word Pattern, 太容易出现了,针对性分析下。

 

 

829 · 字模式 II

算法

困难

通过率47%

 

描述

给定一个pattern和一个字符串str,查找str是否遵循相同的模式。
这里遵循的意思是一个完整的匹配,在一个字母的模式和一个非空的单词str之间有一个双向连接的模式对应。(如果a对应s,那么b不对应s。例如,给定的模式= "ab", str = "ss",返回false)。

您可以假设模式str只包含小写字母

样例

样例1

输入:
pattern = "abab"
str = "redblueredblue"
输出: true
说明: "a"->"red","b"->"blue"

样例2

输入:
pattern = "aaaa"
str = "asdasdasdasd"
输出: true
说明: "a"->"asd"

样例3

输入:
pattern = "aabb"
str = "xyzabcxzyabc"
输出: false
class Solution:
    """
    @param pattern: a string,denote pattern string
    @param str: a string, denote matching string
    @return: a boolean
    """
    def wordPatternMatch(self, pattern, string):
        return self.is_match(pattern, string, {}, {})

    def is_match(self, pattern, string, mapping, mapping2):
        if not pattern:
            return not string
            
        char = pattern[0]
        if char in mapping:
            word = mapping[char]
            if not string.startswith(word):
                return False
            return self.is_match(pattern[1:], string[len(word):], mapping, mapping2)
            
        for i in range(len(string)):
            word = string[:i + 1]
            if word in mapping2:
                continue
            
            mapping2[word] = char
            mapping[char] = word
            
            if self.is_match(pattern[1:], string[i + 1:], mapping, mapping2):
                return True
            
            del mapping[char]
            del mapping2[word]
                        
        return False

  

要点:

if word in mapping2:
      continue
理解下:
这里我们为什么需要一个额外的 mapping2 呢? 
		  
			一个好的测试用例是:
			pattern:    "bdpbibletwuwbvh"
			str:        "aaaaaaaaaaaaaaa"
			
		 这里第一次执行时, mapping中匹配了 b -> a 
		 递归进去以后第二次执行时,d 没有在 mapping 中,所以跳过了map的匹配检测,
		 所以进入循环体, 这时第二个word 又是 a, 按道理 a 应该被 b 匹配并且之前应该在mapping.containsKey的检查中跳出, 但现在并没有跳出,而是试图绑匹配给另一个pattern的字母 d, 
		 很明显 b != d 重复绑定不是正确结果, 所以需要continue掉这次尝试。
		 
		 当然, 我们可以直接用map.containsValue(d), 因为之前map检查中己经跳出了如果己经绑定过,现在又出现了,就意味着重复绑定, 或者说不是匹配的。 
                之所以单独开了这个mapping2 因为map.containsValue需要额外的O(n)时间, 实际上就是以空间换时间或时间换空间的选择。

 

单词接龙 II · Word Ladder II

给出两个单词(startend)和一个字典,找出所有从startend的最短转换序列。

变换规则如下:

  1. 每次只能改变一个字母。
  2. 变换过程中的中间单词必须在字典中出现。
  3. 所有单词具有相同的长度。
  4. 所有单词都只包含小写字母。
  5. 题目确保存在合法的路径。

样例

样例 1:

输入:

start = "a"
end = "c"
dict =["a","b","c"]

输出:

[["a","c"]]

解释:

"a"->"c"

样例 2:

输入:

start ="hit"
end = "cog"
dict =["hot","dot","dog","lot","log"]

输出:

[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]

解释:

1."hit"->"hot"->"dot"->"dog"->"cog"
2."hit"->"hot"->"lot"->"log"->"cog"

用dijstra算法会出现mem超出限制!!!
先用bfs找到target距离,再用dfs寻找路径,会超时。。。你妹哦!
from typing import (
    List,
    Set,
)
import heapq


class Solution:
    """
    @param start: a string
    @param end: a string
    @param dict: a set of string
    @return: a list of lists of string
             we will sort your return value in output
    """
    def find_ladders(self, start: str, end: str, dict: Set[str]) -> List[List[str]]:
        # write your code here
        self.next_word_dict = {}
        distance = self.bfs(start, end, dict)
        self.ans = []
        print("distance", distance)
        
        self.dfs(start, end, dict, distance, layer=0, path=[start])
        return self.ans

    def bfs(self, start, end, mapping):        
        mapping.add(end)

        q = [start]
        seen = {start}
        distance = 0

        while q:
            # print("q=>", q)            
            q2 = []
            distance += 1
            for virtex in q:
                for word in self.get_neibors(virtex, mapping):                
                    if word not in seen:
                        q2.append(word)                    
                        seen.add(word)

                    if word == end:
                        return distance
            #print("q", q)
            #print("q2", q2)
            q = q2
                    
        return distance
    
    def get_neibors(self, word, words_set):
        if word in self.next_word_dict:
            return self.next_word_dict[word]

        words = []
        for i in range(len(word)):
            left, right = word[:i], word[i + 1:]
            for char in 'abcdefghijklmnopqrstuvwxyz':
                if word[i] == char:
                    continue
                 
                word2 = left + char + right              
                if word2 in words_set:                   
                    words.append(word2)
        
        self.next_word_dict[word] = words
        return words

    def dfs(self, start, end, mapping, distance, layer, path):
        if layer == distance:
            if end == start:
                self.ans.append(list(path))
            return
        
        for word in self.get_neibors(start, mapping):   
            # if word not in path:  
            if len(path) < 2 or word != path[-2]:              
                path.append(word)
                # print("paht:", path)
                self.dfs(word, end, mapping, distance, layer+1, path)
                path.pop()
优化下,使用distance记录bfs中的节点到start的距离,然后在dfs遍历中,看是否满足距离,这样去卡dfs的节点:(使用BFS的原因为了预处理出最短路径。如果只使用DFS会超时因为会遍历所有的可能。)
from typing import (
    List,
    Set,
)
import heapq


class Solution:
    """
    @param start: a string
    @param end: a string
    @param dict: a set of string
    @return: a list of lists of string
             we will sort your return value in output
    """
    def find_ladders(self, start: str, end: str, dict: Set[str]) -> List[List[str]]:
        # write your code here
        self.next_word_dict = {}
        distance = self.bfs(start, end, dict)
        self.ans = []
        # print("distance", distance)
        
        self.dfs(start, end, dict, distance, layer=0, path=[start])
        return self.ans

    def bfs(self, start, end, mapping):        
        mapping.add(end)

        q = [start]
        seen = {start}
        distance = {}
        layer = 0

        while q:       
            q2 = []
            layer += 1
            for virtex in q:
                for word in self.get_neibors(virtex, mapping):                
                    if word not in distance:
                        q2.append(word)                    
                        distance[word] = layer

                    if word == end:
                        return distance

            q = q2
                    
        return distance
    
    def get_neibors(self, word, words_set):
        if word in self.next_word_dict:
            return self.next_word_dict[word]

        words = []
        for i in range(len(word)):
            left, right = word[:i], word[i + 1:]
            for char in 'abcdefghijklmnopqrstuvwxyz':
                if word[i] == char:
                    continue
                 
                word2 = left + char + right              
                if word2 in words_set:                   
                    words.append(word2)
        
        self.next_word_dict[word] = words
        return words

    def dfs(self, start, end, mapping, distance, layer, path):
        if end == start:
            self.ans.append(list(path))
            return
        
        for word in self.get_neibors(start, mapping):   
            if word in distance and distance[word] == layer+1:
                path.append(word)
                self.dfs(word, end, mapping, distance, layer+1, path)
                path.pop()

  

单词搜索 II · Word Search II

深度优先搜索/回溯法哈希表微软爱彼迎谷歌LintCode Copyright字典树

描述中文

给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动。一个字母在一个单词中只能被使用一次。且字典中不存在重复单词

样例

样例 1:

输入:["doaf","agai","dcan"],["dog","dad","dgdg","can","again"]
输出:["again","can","dad","dog"]
解释:
  d o a f
  a g a i
  d c a n
矩阵中查找,返回 ["again","can","dad","dog"]。

样例 2:

输入:["a"],["b"]
输出:[]
解释:
 a
矩阵中查找,返回 []。

挑战

使用单词查找树来实现你的算法

 

直接暴力做要悲剧,todo,trie写下。。。

 

标签:distance,Search,Word,Pattern,self,end,return,start,word
From: https://blog.51cto.com/u_11908275/6888022

相关文章

  • remote: Support for password authentication was removed on August 13, 2021
    一、问题描述remote:SupportforpasswordauthenticationwasremovedonAugust13,2021.Pleaseuseapersonalaccesstokeninstead.具体如下:  大概意思:你原先的密码凭证从2021年8月13日开始就不能用了,必须使用个人访问令牌(personalaccesstoken),就是把你的密码替......
  • ElasticSearch——使用备忘
    查询GEThttp://xxxxx:9200/user_list/_search 添加模板POSThttp://xxxxx:9200/user_list/_scripts/user_list_template{"script":{"lang":"mustache","source":"{\"query\":{\"bool\":{\&qu......
  • Elastic Search 安装部署最全教程(Docker)
    @@dockeres安装https://blog.csdn.net/Grey_fantasy/article/details/131561847 https://blog.csdn.net/qq_33034733/article/details/130857381 https://blog.csdn.net/yueyue763184/article/details/128138329 ElasticSearch安装部署最全教程(Docker)一、部......
  • CKEditor上传图片word
    ​ 1.编辑器修改(可选)1.1在 ueditor/config.json 中添加代码块    /* 上传word配置 */    "wordActionName":"wordupload",/* 执行上传视频的action名称 */    "wordFieldName":"upfile",/* 提交的视频表单名称 */    "wordPathFormat":"/p......
  • PageOffice在线只读打开word文件并禁止复制
    一、PageOffice禁止复制1、poCtrl.setAllowCopy(false);//禁止拷贝,权限比较大,系统的快捷键Ctrl+C,Ctrl+V也会受到影响,但是可以在其他程序中可以使用右键菜单进行拷贝粘贴操作2、wordDoc.setDisableWindowSelection(true);//禁止word的选择文字功能3、poCtrl.setDisableCopyOnly......
  • FCKEditor上传图片word
    ​图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,找到UM.plugins['autoupload'],然后找到autoUploadHandler方法,注释掉其中的代码。加入下面的代码://判断剪贴......
  • KindEditor上传图片word
    ​ 这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@     page contentType="text/html;cha......
  • wangEditor上传图片word
    ​  自动导入Word图片,或者粘贴Word内容时自动上传所有的图片,并且最终保留Word样式,这应该是Web编辑器里面最基本的一个需求功能了。一般情况下我们将Word内容粘贴到Web编辑器(富文本编辑器)中时,编辑器都无法自动上传图片。需要用户手动一张张上传Word图片。如果只有一张图片还能......
  • fluent elasticsearch6 fluent-plugin-elasticsearch install
    一、安装fluent-plugin-elasticsearch编写DockerfileFROMfluent/fluentd:v1.12.0-debian-1.0USERrootRUNgemuninstall-Ielasticsearch&&geminstallelasticsearch-v6.8.0RUN["gem","install","fluent-plugin-elasticsearch&qu......
  • wordpress 插件 woocommerce自定义订单信息验证
    使用php钩子函数增加自定义验证add_action('woocommerce_after_checkout_validation',function($fields){if($fields['billing_phone']&&!preg_match('/^((\+1|1)?(|-)?)?(\([2-9][0-9]{2}\)|[2-9][0-9]{2})(|-)?([2-9][0-9]{2}(|-)?[0-9......