[LeetCode]567. Permutation in String

567. Permutation in String

一开始想到的就是计算出所有的排列,然后一一判断是否是子串,但是TLE。

class Solution(object):
    def checkInclusion(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: bool
        """
        def backtracking(index, strs):
            if index >= len(strs):
                res.append(''.join(strs[:]))
                return
            for i in range(index, len(strs)):
                if i > index and strs[i] == strs[i - 1]:
                    continue
                strs[i], strs[index] = strs[index], strs[i]
                backtracking(index+1, strs)
                strs[index], strs[i] = strs[i], strs[index]
        if not s1 and not s2:
            return True
        elif not s1 or not s2:
            return False
        res = []
        strs = list(s1)
        backtracking(0, strs)
        for n in res:
            if s2.find(n) != -1:
                return True
        return False

一开始自己还以为会是像纪录字符串两边的坐标,然后分别进行移动缩小区间,但其实不然,因为这种情况通常用来明确知道是向左移动还是向右移动的情况,比如在已经拍好序的数组中,但是这是字符串,而且无序,没有肯定方向的概念,所以否定掉。

后来发现是自己对于全排列的理解不够,其实只要它们的元素相同,其对应的个数相同,那么一个字符串必然属于另外一个字符串的全排列,那么问题就变成了纪录元素和元素个数,Python提供Counter非常方便,维护一个窗口,超出则删掉。

import collections
class Solution(object):
    def checkInclusion(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: bool
        """
        counter, window = collections.Counter(s1), collections.Counter('')
        for i, n in enumerate(s2):
            window[n] += 1
            if i >= len(s1):
                window[s2[i-len(s1)]] -= 1
                if window[s2[i-len(s1)]] <= 0:
                    del window[s2[i-len(s1)]]
            if window == counter:
                return True
        return False
posted @ 2017-08-31 15:10  banananana  阅读(159)  评论(0编辑  收藏  举报