劍指offer第二版-48.最長不含重復字符的子字符串(動態規劃)

本系列導航:劍指offer(第二版)java實現導航帖

面試題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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容