您的位置:首页 > 其它

求最长不重复子串

2018-02-27 10:29 148 查看
问题描述:给定一个字符串,找出这个字符串中最长的不重复子串。比如对于字符串“sadus”,那么返回的结果应该是“sadu”或者“adus”(返回一个即可);对于字符串“acbba”,返回的应是“acb”。       对于这样一个问题,想必大家首先想到利用的数据结构是HashMap,利用HashMap来保证子串的不重复。但是我们可以想想能不能不用HashMap呢?答案显然是可以的,因为字符数是固定的,不超过256个!所以我们可以用一个长度为256的数组来记录所有字符的出现情况。       具体的思路是这样的:遍历整个字符串,针对每个字符做三件事(1)   如果当前字符出现过并且该字符上一次出现时的index大于目前子串的初始index,那么将目前子串的初始index置为该字符上一次出现时的index。注意这个子串不一定是最大长度的子串,而是程序运行过程中当前的不重复子串。(2)   如果当前的index与startIndex(目前子串的初始index)的差值大于maxLen(记录的最长不重复子串的长度),那么更新maxLen。注意,因为我们要输出这个不重复子串,所以我们在这时候(maxLen改变时)需要记录startIndex。(3)   记录当前字符的index。这样扫描完以后,我们就可以根据oriStartIndex(maxLen改变时记录的startIndex)和maxLen来得到最长不重复子串。具体实现如下,其中findLongestSubString1()函数是利用HashMap来实现的,而findLongestSubString2()函数是利用数组来实现的,两者的算法思想是一模一样的,但是性能相差近10倍。[java] view plain copyimport java.util.HashMap;  
  
public class MaxSubString {  
  
    public static void main(String[] args) {  
          
        String str = "jhhjnsfudufbdfyscfbsdjjSAFASFsefyrsjksaudhsduhasdbg" +  
                "ywqep[m,mzaASFASFhuwenzsdjsjfasfyaehwzsjx ;ASFASFlpwisjd" +  
                "asuwnad.pqwekASFqowe92347174nsd sdfsdf73bwASFawue821b9sa" +  
                "dasjdnasdqASFASASFF2en128adasjdnqwudSAASFF ASFw 1wq89ewa" +  
                "dasjdASFhqw8edeqwhedhqwueASFuquweuqwuehqw e123xrkASFajs8" +  
                "9da2qe54we24eDASASAFFdfsdifhsd";  
        long a = System.nanoTime();  
        for(int count = 0; count < 100000; count++){  
            findLongestSubString1(str);  
        }  
        long b = System.nanoTime() - a;  
        System.out.println(b);  
          
        a = System.nanoTime();  
        for(int count = 0; count < 100000; count++){  
            findLongestSubString2(str);  
        }  
        b = System.nanoTime() - a;  
        System.out.println(b);  
          
        System.out.println(findLongestSubString1(str));  
        System.out.println(findLongestSubString2(str));  
    }  
      
    private static String findLongestSubString1(String str) {  
        if(str == null) return null;  
        StringBuilder maxSubString = new StringBuilder("");  
        char [] strCharArr = str.toCharArray();  
        HashMap<Character, Integer> charsIndex = new HashMap<Character, Integer>();  
        int startIndex = -1, oriStartIndex = startIndex, maxLen = 0;  
        for(int index = 0; index < strCharArr.length; index++) {  
            if(charsIndex.containsKey(strCharArr[index])) {  
                int oriIndex = charsIndex.get(strCharArr[index]);  
                if(oriIndex > startIndex){  
                    startIndex = oriIndex;  
                }  
            }  
            if(index - startIndex > maxLen) {  
                maxLen = index - startIndex;  
                oriStartIndex = startIndex;  
            }  
            charsIndex.put(strCharArr[index], index);  
        }  
        for(int index =  oriStartIndex + 1; index < oriStartIndex + maxLen + 1; index++) {  
            maxSubString.append(strCharArr[index]);  
        }  
        return maxSubString.toString();  
    }  
      
    private static String findLongestSubString2(String str) {  
        if(str == null) return null;  
        StringBuilder maxSubString = new StringBuilder("");  
        char [] strCharArr = str.toCharArray();  
        int [] charsIndex = new int[256];  
        for(int index = 0; index < 256; index++) charsIndex[index] = -1;  
        int startIndex = -1, oriStartIndex = startIndex, maxLen = 0;  
        for(int index = 0; index < strCharArr.length; index++) {  
            if(charsIndex[strCharArr[index]] > startIndex)  
                startIndex = charsIndex[strCharArr[index]];  
            if(index - startIndex > maxLen) {  
                maxLen = index - startIndex;  
                oriStartIndex = startIndex;  
            }  
            charsIndex[strCharArr[index]] = index;  
        }  
        for(int index =  oriStartIndex + 1; index < oriStartIndex + maxLen + 1; index++) {  
            maxSubString.append(strCharArr[index]);  
        }  
        return maxSubString.toString();  
    }  
}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: