leetcode(76)- 最小覆盖子串

76.最小覆盖子串
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

思路

这题目说实话有点小难啊,因为要处理字符串,我写的是大量的字符串删除操作、拼接操作,运行速度太慢了,以至于无法通过最后一个测试用例。。。最后一个用例属实恶心,一共10004个字符,先跳过它吧,记录下解题思路。
特点:首先我们可以发现输出串有一个特点,他的首尾字符必然是目标串T中的。
算法模板如下:

从S的首字符往后检索
if 当前字符在串T中
{
	删除T中的这个字符
	if 串T的长度为0
	{
		记录当前遍历串的起始位置和结束位置
		比较记录的长度是不是最短
		break;
	}
	从当前位置向后继续遍历串S
	if 当前字符在串T中
	{
		删除这个字符
		if 串T的长度为0
		{
			记录当前遍历串的起始位置和结束位置
			比较记录的长度是不是最短
			break;
		}
	}
}

这里删除串中的一个字符在java的库函数里面没有找到对应的函数,于是自己实现了一个:

public static String removeCharAt(String s, int pos) {
    if(pos == s.length() - 1)
    	return s.substring(0, pos);
    else
    	return s.substring(0, pos) + s.substring(pos + 1);
}
  • 这样会造成大量的字符串拼接,速度极慢。
  • 判断字符是不是在串中使用了函数indexof,这每次都需要从头往后遍历字符串,而不如哈希表那样查找键值来的快。

哈希表是直接通过哈希值计算出键值位置的,在查找速度上快了很多倍,感觉哈希表查找元素就和数组查找第几项这样,有一个公式可以直接访问到哪一项的内存,然后indexof函数查找第几项就像链表一样需要从头往后检索。

代码实现

class Solution {
    public String minWindow(String s, String t) {
        if(t.length() > s.length())
    		return "";
        if(t.equals(s))
        	return t;
    	int minLength = 1000000;
    	int start = 0,end = 0;
    	for(int i = 0; i < s.length();)
    	{
    		int first_index = -1;
    		int indexOft = t.indexOf(s.charAt(i));
    		if(indexOft != -1)
    		{
    			String t_temp = removeCharAt(t, indexOft);
				if(t_temp.length() == 0)
				{
					minLength = 1;
					start = i;
					end = i;
					break;
				}
    			for(int j = i + 1; j < s.length(); j++)
    			{
    				indexOft = t_temp.indexOf(s.charAt(j));
					if(first_index == -1 && t.indexOf(s.charAt(j)) != -1)
					{
						first_index = j;//下次从这开始
					}
    				if(indexOft != -1)
    				{
    					t_temp = removeCharAt(t_temp, indexOft);
    					
        				if(t_temp.length() == 0)
        				{
        					if(j - i < minLength)
        					{
        						minLength = j - i;
        						start = i;
        						end = j;
        					}
        					break;
        				}
    				}
    			}
    		}
			if(first_index != -1)
				i = first_index;//从记录位置开始
			else
				i++;
    	}
    	if(minLength == 1000000)
    		return "";
    	else
    		return s.substring(start,end + 1);
    }
    public static String removeCharAt(String s, int pos) {
    	if(pos == s.length() - 1)
    		return s.substring(0, pos);
    	else
    		return s.substring(0, pos) + s.substring(pos + 1);
     }
}

哎,写的属实太乱了一点都不美观,可以之后尝试下使用HashMap来解决这个问题,我这应该也算是使用了滑动窗口的算法思想吧。

发布了81 篇原创文章 · 获赞 21 · 访问量 8809

猜你喜欢

转载自blog.csdn.net/qq_37668436/article/details/105218361