KMP与leetcode 28. Implement strStr()

https://www.zhihu.com/question/21923021/answer/281346746

知乎的这位老哥解释的不能再清楚了,我就不再重复,就突出一些重点

KMP算法的核心,是一个被称为部分匹配表(Partial Match Table)的数组。 PMT中的值是字符串的前缀集合与后缀集合(前后缀都不包含本身)的交集中最长元素的长度(或最长公共前后缀)。例如,对于”aba”,它的前缀集合为{”a”, ”ab”},后缀 集合为{”ba”, ”a”}。两个集合的交集为{”a”},那么长度最长的元素就是字符串”a”了,长 度为1,所以对于”aba”而言,它在PMT表中对应的值就是1。再比如,对于字符串”ababa”,它的前缀集合为{”a”, ”ab”, ”aba”, ”abab”},它的后缀集合为{”baba”, ”aba”, ”ba”, ”a”}, 两个集合的交集为{”a”, ”aba”},其中最长的元素为”aba”,长度为3。我们看到如果是在 j 位 失配,那么影响 j 指针回溯的位置的其实是第 j −1 位的 PMT 值,所以为了编程的方便, 我们不直接使用PMT数组,而是将PMT数组向后偏移一位。我们把新得到的这个数组称为next数组。

void getNext(char * p, int * next)
{
	next[0] = -1;
	int i = 0, j = -1;

	while (i < strlen(p))
	{
		if (j == -1 || p[i] == p[j])
		{
			++i;
			++j;
			next[i] = j;
		}	
		else
			j = next[j];
	}
}

int KMP(char * t, char * p) 
{
	int i = 0; 
	int j = 0;

	while (i < strlen(t) && j < strlen(p))
	{
		if (j == -1 || t[i] == p[j]) 
		{
			i++;
           		j++;
		}
	 	else 
           		j = next[j];
    	}

    if (j == strlen(p))
       return i - j;
    else 
       return -1;
}

推荐看原知乎回答。

leetcode:28. Implement strStr()

Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "hello", needle = "ll"
Output: 2

Example 2:

Input: haystack = "aaaaa", needle = "bba"
Output: -1

Clarification:

What should we return when needle is an empty string? This is a great question to ask during an interview.

For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().

题意:如果字符needle在haystack中,就返回第一个索引,如果不在,返回-1

解析:这是典型KMP的使用

class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        #if(not needle in haystack):
        #    return -1
        #else:
        #    return haystack.index(needle)
        if (needle==""):
            return 0
        next=[]
        next=self.get_next(haystack,needle)
    
        print(next)
        ii=0
        jj=0
        while(ii<len(haystack) and jj<len(needle)):
            if(jj==-1 or haystack[ii]==needle[jj]):
                ii+=1
                jj+=1
            else:
                jj=next[jj]
                
        if(jj==len(needle)):
            return ii-jj
        else:
            return -1
        
    def get_next(self,haystack,needle):
        next=[-5 for i in range(len(needle))]
        next[0]=-1
        i=0
        j=-1
        length=len(needle)
        while(i<length-1):
            if(j==-1 or needle[i]==needle[j]):
                i+=1
                j+=1
                next[i]=j
            else:
                j=next[j]
        return next
            
                
            

459. Repeated Substring Pattern

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.

 

Example 1:

Input: "abab"
Output: True
Explanation: It's the substring "ab" twice.

Example 2:

Input: "aba"
Output: False

Example 3:

Input: "abcabcabcabc"
Output: True
Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)

题意:判断数组是否是重复的

解法1:简单解法:如果一个数组是重复的,那最少是重复两遍的,如果把两个他进行叠加,然后把头和尾的元素去掉,那么此时数组包含一个原数组,如果原数组重复三遍,此时应该包含4/3个原数组。而且随着原数组重复次数增减,包含的数组个数也是递增的。如果一个数组不是重复的,那叠加后如果去掉首尾元素,原数组是不存在其中的

class Solution(object):
    def repeatedSubstringPattern(self, s):
        """
        :type s: str
        :rtype: bool
        """
        s2=s+s
        if(s in s2[1:-1]):
            return True
        return False

解法2:用KMP的思想,其实就是求next,如果next最后(比平时的next要多计算一个)一个元素不等于0,而且是能被不重复数组长度整除(即能得到的重复次数是整数),就返回True

class Solution(object):
    def repeatedSubstringPattern(self, s):
        """
        :type s: str
        :rtype: bool
        """
        '''
        s2=s+s
        if(s in s2[1:-1]):
            return True
        return False
        '''
        next=[-5 for i in range(len(s)+1)]
        next[0]=-1
        i=0
        j=-1
        length=len(s)
        while(i<length):
            if(j==-1 or s[i]==s[j]):
                i+=1
                j+=1
                next[i]=j
            else:
                j=next[j]
        print(next)
        return next[-1] and  length%(length-next[-1])==0
        

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值