[LeetCode]Is Subsequence

392. Is Subsequence

這道題目可使用不少種解法,包括是動態規劃等等。html

動態規劃

s爲匹配字符串,t爲給定字符串假設dp[i][j]表示t從開始到第i個字符時對應s從開頭到第j個字符,s所否是t的子序列。python

分析:在比較的過程當中,若是t[i]不等於s[j],則忽略掉當前的字符,取以前i-1匹配的狀況,若是是相等,則取決於雙方上一位的匹配的狀況,這裏注意的是,若是匹配字符串爲空,那麼結果爲True。web

class Solution(object):
    def isSubsequence(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if not s and not t:
            return True
        elif not s and t:
            return True
        elif not t and s:
            return False
        m, n = len(t), len(s)
        dp = [[False for i in range(n + 1)] for j in range(m + 1)]
        dp[0][0] = True
        for i in range(1, m + 1):
            dp[i][0] = True
        for i in range(1, n + 1):
            dp[0][i] = False
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if t[i-1] == s[j-1]:
                    dp[i][j] = dp[i - 1][j - 1]
                else:
                    dp[i][j] = dp[i - 1][j]
        return dp[m][n]

但由於空間的複雜度過大致使了TLE,因此須要再進一步的進行優化,由於咱們只使用到了上一行的狀態,所以咱們能夠只使用兩行,而後使用完的時候進行交換便可。數組

class Solution(object):
    def isSubsequence(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if not s and not t:
            return True
        elif not s and t:
            return True
        elif not t and s:
            return False
        m, n = len(t), len(s)
        dp = [[False for j in range(m + 1)] for i in range(2)]
        for i in range(m + 1):
            dp[0][i] = True
        for i in xrange(1, n+1):
            for j in xrange(1, m+1):
                if s[i-1] == t[j-1]:
                    dp[1][j] = dp[0][j-1]
                else:
                    dp[1][j] = dp[1][j-1]
            dp[0] = dp[1][:]
        return dp[1][m]

可是,依舊是TLE,咱們繼續在它的基礎之上進行優化,由於只有在不相等的狀況的時候纔會使用到上一行的狀態,並且只用到了它的值,所以,咱們使用一個變量來進行維護。app

不會

二分搜索

一開始我看到這個方法的時候,竟然傻傻的去對字符串進行搜索😳。函數

思路:紀錄給定字符串每一個字符對應的位置,維護前一個字符的位置,而後遍歷匹配字符串去找到比前一個字符位置要大的位置,可是又不能超出數組長度,由於這樣顯然是由於前一個字符在不存在。優化

import collections
class Solution(object):
    def isSubsequence(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        def binary_search(nums, x):
            low, high = 0, len(nums)
            while low < high:
                mid = (low + high) // 2
                if nums[mid] < x:
                    low = mid + 1
                else:
                    high = mid
            return high
        if not s and not t:
            return True
        elif not s and t:
            return True
        elif not t and s:
            return False
        pre_idx = 0
        idxs = collections.defaultdict(list)
        for i,n in enumerate(t):
            idxs[n].append(i)
        for i in range(len(s)):
            idx = binary_search(idxs[s[i]], pre_idx)
            if idx != len(idxs[s[i]]):
                pre_idx = idxs[s[i]][idx] + 1
            else:
                return False
        return True

貪心

其實上面的作法也是貪心的思想,只要後者比前者大就更新,那這裏就直接使用內建函數indexui

class Solution(object):
    def isSubsequence(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if not s and not t:
            return True
        elif not s and t:
            return True
        elif not t and s:
            return False
        pre_idx = -1
        for i in range(len(s)):
            idx = t.find(s[i], pre_idx+1)
            if idx != -1:
                pre_idx = idx
            else:
                return False
        return True

滑動窗口

移動窗口本質也是貪心的思想,以前的動態規劃時間複雜度爲O(n^2),二分搜索優化到了O(nlogn),滑動窗口則直接優化到了O(n)。spa

思路:每當匹配字符串中的字符和給定字符串中的字符相等時,則移動匹配下標,其他均移動給定字符串下標,查看最後移動下標是否到達最後。code

class Solution(object):
    def isSubsequence(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if not s and not t:
            return True
        elif not s and t:
            return True
        elif not t and s:
            return False
        m, n = len(s), len(t)
        si, ti = 0, 0
        while si < m and ti < n:
            if s[si] == t[ti]:
                si += 1
            ti += 1
        return si == m
相關文章
相關標籤/搜索