LeetCodeブラッシングノート_76。最小カバレッジサブストリング

トピックはLeetCodeからです

76.最小被覆部分文字列

他のソリューションまたはソースコードにアクセスできます:tongji4m3

解説

文字列Sと文字列Tを与えます。文字列SからO(n)時間の複雑さ内で検出できるアルゴリズムを設計してください:Tのすべての文字を含む最小の部分文字列。

例:

输入:S = "ADOBECODEBANC", T = "ABC"
输出:"BANC"

促す:

如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

アイデア

スライディングウィンドウの方法:最初にhiを拡張してTを含め、次にloを増やして要件を満たさなくなるまで最小化します。ループを続けてこんにちは

//初步思路
int lo=0,hi=0;//左右指针,指向最小覆盖子串的首尾
int result=0;
while(hi<N) 
{	
	while([lo,hi]区间包含T)
	{
		result=max(result,hi-lo+1);
		++lo;//增加lo
	}
	++hi;//扩大hi
}

キーは判断する方法です:[lo、hi]区間にはTが含まれます

Tの文字と出現回数をマップに保存することができます。Tの文字がループに現れる場合、それらはウィンドウに追加されます

値を使用して、マップとWindowsの文字との一致を判別します(文字が同じ回数出現する場合、一致します)

int lo=0,hi=0;//左右指针,指向最小覆盖子串的首尾
int match=0;//匹配情况

for ch in T:
	map.put(ch,map.get(ch)+1)

while(hi<N) 
{
	char ch=T[hi]
	if(map.contains(ch))
	{
		window.put(ch,window.get(ch)+1);
		if(map.get(ch)==window.get(ch)) ++match; //windows中该字符太多不会匹配多次
	}
	//说明至少包含了T所有字符
	while(match==map.size())
	{
		result=max(result,hi-lo+1);
		if(map.contains(T[lo])) //说明滑动了一个T中字符
		{
			window.put(T[lo],window.get(T[lo])-1);//look ch代表的是T[hi]
			if(map.get(T[lo])>window.get(T[lo])) --match;
		}
		++lo;//增加lo
	}
	++hi;//扩大hi
}

コード

public String minWindow(String s, String t)
{
    
    
    int lo=0,hi=0;//左右指针,指向最小覆盖子串的首尾
    int start=0,length=Integer.MAX_VALUE;//look 记录结果 求最小,length应该为最大
    int match = 0;//匹配情况

    Map<Character, Integer> map = new HashMap<>();
    Map<Character, Integer> window = new HashMap<>();//代表滑动窗口
    for (char ch : t.toCharArray())
    {
    
    
        map.put(ch, map.getOrDefault(ch, 0) + 1);
    }

    while(hi<s.length())
    {
    
    
        char chHi = s.charAt(hi);//look 命名为ch可能导致下面误导用ch表示S[lo]
        if(map.containsKey(chHi)) //如果出现了T中字符,则放入
        {
    
    
            window.put(chHi, window.getOrDefault(chHi, 0) + 1);
            if(map.get(chHi).equals(window.get(chHi))) ++match; //windows中该字符太多不会匹配多次
        }
        while(match==map.size())
        {
    
    
            if(length>hi-lo+1)
            {
    
    
                length = hi - lo + 1;
                start = lo;
            }
            char chLo = s.charAt(lo);
            if(map.containsKey(chLo)) //说明滑动了一个T中字符
            {
    
    
                window.put(chLo,window.get(chLo)-1);
                if(map.get(chLo)>window.get(chLo)) --match;
            }
            ++lo;//增加lo
        }

        ++hi;//扩大hi
    }
    //如果不包含这样的子串,那length没变
    if(length==Integer.MAX_VALUE) return "";
    return s.substring(start,start+length);
}

おすすめ

転載: blog.csdn.net/weixin_42249196/article/details/108333212