LeetCode 笔记(一)

题目 Regular Expression Match

正则表达式匹配问题,’.’表示匹配单个字符,’*‘表示匹配大于等于0个前面的字符。匹配的话需要包含整个输入字符串

之前一直没注意preceding这个词,导致我一直没看懂题目TAT

s是输入字符,p是正则表达式pattern

isMatch(“aa”,”a”)->false 没有包含整个输入字符串
isMatch(“aa”,”aa”)->true
isMatch(“aa”,”a*”)->true
isMatch(“aa”,”.*”)->true
isMatch(“aab”,”c*a*b”)->true 因为c*a*b包含了aab的情况
isMatch(“aab”,”ca*b”)->false 因为c*a*b包含了aab的情况isMatch(“abcd”,”b*”)->false

*假设s=abbba,p=a*bba
当前比较的下标是s为i,p为pi
(1)p[pi+1]不是*。情况比较简单,只要判断当前s的i和p的j上的字符是否一样(如果有p在j上的字符是’.’,也是相同),如果不同,返回false,否则,递归下一层i+1,j+1;
(2)p[pi+1]是*。那么此时看从s[i]开始的子串,假设s[i],s[i+1],…s[i+k]都等于p[j]那么意味着这些都有可能是合适的匹配,那么递归对于剩下的(i,j+2),(i+1,j+2),…,(i+k,j+2)都要尝试(j+2是因为跳过当前和下一个*字符)。

题目30. Substring with Concatenation of All Words

给定单词数组words=[“foo”,”bar”],找到字符串str中包含words的所有单词的任意顺序的子串

最开始的思路是用itertools.permutation把words的所有单词的全排列写出来,但是这样会出现内存溢出。
第二个思路是用wordsnum*wordlen大小的窗口去遍历str,然后截出每个单词看看是否在集合words中,在这里把list转换成了set。但是list中可能会出现重复的单词,所以有麻烦。
第三个思路是先用字典记录每个词出现的个数,然后在对窗口中的每个单词判断是否在集合中,并且计数,一旦超过给定次数则失败,但是这种方法在测试的时候1062ms,但是提交的时候就超时了。

        class Solution(object):
        def findSubstring(self, s, words):
            """
            :type s: str
            :type words: List[str]
            :rtype: List[int]
            """
            worddir={}
            index=[]
            if len(words)==0:
                return
            for i in range(len(words)):
                if worddir.has_key(words[i]):
                    worddir[words[i]]+=1
                else:
                    worddir[words[i]]=1
            wlen=len(words)*len(words[0])
            for i in range(len(s)-wlen+1):
                k=0
                wordset = set(words)
                count={}
                while len(wordset)>0 and s[i+k:i+k+len(words[0])]in wordset:
                    tmp = s[i+k:i+k+len(words[0])]
                    if count.has_key(tmp):
                        count[tmp]+=1
                    else:
                        count[tmp]=1
                    if count[tmp]==worddir[tmp]:            
                        wordset.remove(tmp)
                    k+=len(words[0])
                if k==wlen:
                    index.append(i)
                i+=1
            return index

最后是用到一个滑动窗口来解决的

class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        worddir={}
        index=[]
        initwords=set()
        if len(words)==0:
            return
        for i in range(len(words)):
            if worddir.has_key(words[i]):
                worddir[words[i]]+=1
            else:
                worddir[words[i]]=1
                initwords.add(words[i])
        wlen=len(words)*len(words[0])
        for i in range(len(words[0])):
            j = i
            wordset = initwords.copy()
            count={}
            start = len(s)
            while j < len(s)-len(words[0])+1:
                subword = s[j:j+len(words[0])]
                #print wordset,subword
                if subword in wordset:
                    if count.has_key(subword):
                        count[subword]+=1
                    else:
                        count[subword]=1
                    if count[subword]==worddir[subword]:            
                        wordset.remove(subword)
                    if start>j:
                        start=j
                    #print subword,count[subword],worddir[subword],len(wordset)
                    if len(wordset)==0:
                        index.append(start)
                else:
                    while start<=j and subword not in wordset:
                            sword=s[start:start+len(words[0])]
                            if count.has_key(sword):
                                wordset.add(sword)
                                count[sword]-=1
                                if subword in wordset:
                                    j-=len(words[0])
                            start+=len(words[0])
                j+=len(words[0])
        return index

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值