📌  相关文章
📜  Python|获取包含给定模式的所有字符的字符串中的最小窗口

📅  最后修改于: 2022-05-13 01:55:04.268000             🧑  作者: Mango

Python|获取包含给定模式的所有字符的字符串中的最小窗口

给定两个字符串strpattern ,有效地找到str中包含 pattern 的所有字符的最小子字符串。

例子:

Input : str = 'geeksforgeeks' pattern = 'gks' 
Output : geeks

Input : str = 'new string' pattern = 'rg' 
Output : ring

方法 #1:使用Python enumerate()
此方法使用Python enumerate()need[k]存储我们需要字符k的次数,missing 表示仍然缺少多少字符。在循环中,首先将新字符添加到窗口中。然后,如果没有任何遗漏,请尽可能从窗口开始删除,然后更新结果。

string = 'new string'
pattern = 'rg'
  
# let's find the index of r and g in String and the
# stor them in index list (index[]) 
index=[]
for x in range(len(pattern)):
    if pattern[x] in string:
        index.append(string.index(pattern[x]))
  
# sorting the r and g index's
index.sort()
  
# save first index in l
l = len(index)
low = int(index[0])
  
# save  last index in h
high = int(index[l-1])
h = high +1
for i in range(low,h):
    print(string[i],end=" ")
输出:
ksf


方法 #2:使用collections.defaultdict()
此方法使用两个默认字典“src”和“dest”。 defaultdict的工作方式与普通 dict 完全相同,但它使用不带参数的函数(“默认工厂”)进行初始化。 source为空,而target由作为键的模式元素和作为值的出现计数组成。在每次迭代“i”中,我们检查str第 i元素是否存在于目标字典中,并相应地更新字典。

# Python3 code to Find the smallest 
# window in a string containing all 
# characters of another string
from collections import defaultdict
import sys
def min_window(str, pattern):
          
        # Function to check validity of source and 
        # destination
        def isValid(i, j):
            for item in j:
                if item not in i or i[item] < j[item]:
                    return False
            return True
          
        source = defaultdict(int)
        target = defaultdict(int)
          
        # Target consist pattern elements and 1 
        # as key:value pair
        for e in pattern:
            target[e] += 1
          
        # Minimum length for window    
        minLen = sys.maxsize
        n = len(str)
        ans, j = '', 0 
        for i in range(n):
              
            # Update source for valid source - target pair
            while j < n and (isValid(source, target) == False):
                source[str[j]] += 1
                j += 1
              
            # Checking validity of source-target pair
            if isValid(source, target):
                if minLen > j-i + 1:
                    minLen = j-i + 1
                    ans = str[i:j]
            source[str[i]] -= 1
        return ans
  
# Driver Code
string = "geekforgeeks"
pattern = "gks"
print(min_window(string, pattern))
输出:
geeks


方法#3:动态方法
在这种方法中,我们使用 for 循环,并且在每次迭代中,比如 i,我们找到以 i 结尾并包含模式中所有字母的最短间隔。这可以通过考虑两个数据结构来完成,即'rpos'和'rdict'。 rpos 是位置的排序列表,其中保留了 str 中模式字符的最右边位置,而 rdict 是从字符到该位置的字典映射。 rdict 的值与 rpos 相同。

# Python3 code to Find the smallest 
# window in a string containing all 
# characters of another string
from collections import Counter, defaultdict
  
def min_window(str, pattern):
      
    rdict, count = defaultdict(list), Counter(pattern)
    rpos, res = [], "" 
      
    # Loop only over c exist in pattern
    for i, c in filter(lambda x: x[1] in pattern, enumerate(str)): 
        if len(rdict) == count: 
  
            # If reached limit, remove
            rpos.remove(rdict.pop(0))
              
        # Add to dict
        rdict[i].append(i)
  
        # Add to list
        rpos.append(i) 
          
        if (len(rpos) == len(pattern) and
           (res =="" or rpos[-1]-rpos[0]
输出:
geeks