面試題48:最長不含重復字符的子字符串
題目要求:
輸入一個字符串(只包含a~z的字符),求其最長不含重復字符的子字符串的長度。例如對于arabcacfr,最長不含重復字符的子字符串為acfr,長度為4。
解題思路:
動態規劃。用dp[]記錄狀態,dp[i]表示以下標為i的字符結尾不包含重復字符的最長子字符串長度。初始化dp[0] = 1,求maxdp。每次可以根據dp的前一個狀態推導出后一個狀態,因此可以省略dp數組,使用一個變量記錄dp值,使用maxdp記錄最大的dp值。
package chapter5;
/**
* Created with IntelliJ IDEA
* Author: ryder
* Date : 2017/8/12
* Time : 19:37
* Description:最長不含重復字符的子字符串
**/
public class P236_LongestSubstringWithoutDup {
//動態規劃
//dp[i]表示以下標為i的字符結尾不包含重復字符的最長子字符串長度
public static int longestSubstringWithoutDup(String str){
if(str==null || str.length()==0)
return 0;
//dp數組可以省略,因為只需記錄前一位置的dp值即可
int[] dp = new int[str.length()];
dp[0] = 1;
int maxdp = 1;
for(int dpIndex = 1;dpIndex<dp.length;dpIndex++){
//i最終會停在重復字符或者-1的位置,要注意i的結束條件
int i = dpIndex-1;
for(;i>=dpIndex-dp[dpIndex-1];i--){
if(str.charAt(dpIndex)==str.charAt(i))
break;
}
dp[dpIndex] = dpIndex - i;
if(dp[dpIndex]>maxdp)
maxdp = dp[dpIndex];
}
return maxdp;
}
public static void main(String[] args){
System.out.println(longestSubstringWithoutDup("arabcacfr"));
System.out.println(longestSubstringWithoutDup("abcdefaaa"));
}
}
運行結果
4
6