首页 > 代码库 > 给定一个字符串,找到包含该字符串所有字符的最短子串

给定一个字符串,找到包含该字符串所有字符的最短子串

这题是豌豆荚二面的一个算法题,和leetcode的某些题目类似。其思路是这样的

  1. 首先遍历一次字符串,求出字符串不同字符的数目
  2. 为每一个字符保存一个列表,记录该字符在字符串中出现的索引;设置待求字符串为s(初始值为源串),记录待求字符串的首字母pStart(初始值为0)
  3. 重新遍历字符串,更新没有遍历的字符的数目,更新当前字符对应的索引列表。如果pStart处字符对应的列表长度大于1,则从索引列表中移出pStart,并将pStart加1,并重复该过程。如果剩余字符数目为0时,且子字符串[pStart:当前索引]比s短,则更新s为当前子字符串[pStart:当前索引]
  4. 返回s
结束之后,你会发现s为待求字符串。你可以在纸上画画看

public class Solution
{
    String getShortestSubString(String s)
    {
        if (s == null || s.length() <= 1)
        {
            return s;
        }
        // 记录目标字符串的起始索引
        int start = 0, end = s.length() - 1;
        // 记录目标字符串的开始位置
        int pStart = 0;
        Map<Character, List<Integer>> map = new HashMap<Character, List<Integer>>();

        for (int i = 0; i < s.length(); i++ )
        {
            map.put(s.charAt(i), null);
        }
        int remainingCharacter = map.keySet().size();
        for (int i = 0; i < s.length(); i++ )
        {
            char c = s.charAt(i);
            if (map.get(c) == null)
            {
                List list = new LinkedList<Integer>();
                map.put(c, list);
                remainingCharacter-- ;
            }
            map.get(c).add(i);
            while (map.get(s.charAt(pStart)).size() > 1)
            {
                map.get(s.charAt(pStart)).remove(0);
                pStart++ ;
            }
            if (remainingCharacter == 0)
            {
                if (i - pStart < end - start)
                {
                    
                    start = pStart;
                    end = i;
                }
            }
        }
        return s.substring(start, end +1);
    }

    @Test
    public void test()
    {
        System.out.println(getShortestSubString("abcddbccaaabcefggf"));
    }
}


给定一个字符串,找到包含该字符串所有字符的最短子串