算法题之——最大子串

来源:互联网 发布:软件合作模式吗 编辑:程序博客网 时间:2024/06/03 06:59

算法题之——最大子串

题目:给定一字符串只包含数字,请写一个算法,找出该字符串中的最长不重复子串(不重复是指子串中每一元素不同于子串中其他元素)
如: “120135435”最长不重复子串为 “201354”

代码:
方法一:

//辅助数组,o(n*n)    private static String noRepeatSubString(String str){        int a[] = new int[10];        int maxlength = 0;        int maxindex = 0;        int j;        for(int i=0;i<str.length();i++){            for(j=0;j<10;j++)                a[j] = 0;            char c = str.charAt(i);            a[c-'0'] = 1;            for(j=i+1;j<str.length();j++){                if(a[str.charAt(j)-'0']==0){                    a[str.charAt(j)-'0'] = 1;                }else{                    if(maxlength<j-i){                        maxlength = j-i;                        maxindex = i;                    }                    break;                }            }            if((j==str.length())&&(j-i>maxlength)){                maxlength = j-i;                maxindex = i;            }        }        System.out.println(maxindex);        return str.substring(maxindex, maxindex+maxlength-1);    }

方法二:

/**     * 数组dp存储到下标i的最大子数组长度     * 比如字符串"aabcdb"     * 则dp[0]=1(a),dp[1]=1(a),dp[2]=2(ab),dp[3]=3(abc),dp[4]=4(abcd),dp[5]=3(cdb)     * o(n*n)     * 可改进     * @param str     * @return     */    private static String noRepeatSubString1(String str){        int dp[] = new int[str.length()];        dp[0] = 1;        int maxlen=0,maxindex = 0;        int last_start = 0;        for(int i=1;i<str.length();i++){            for(int j=i-1;j>=last_start;j--){                if(str.charAt(i)==str.charAt(j)){                    dp[i] = i-j;                    last_start = j+1;                    break;                }else if(j==last_start){                    dp[i] = dp[i-1]+1;                }            }            if(dp[i]>maxlen){                maxlen = dp[i];                maxindex = i+1-maxlen;            }        }        return str.substring(maxindex, maxindex+maxlen-1);    }

方法三:

/**时间复杂度o(n)     * 120135435     * @param str     * @return     */    private static String noRepeatSubString2(String str){        //记录数字出现的位置        int visit[] = new int[10];        //记录到达i的最大子串的长度        int dp[] = new int[str.length()];        int last_start = 0;        int maxlen=0,maxindex=0;        for(int i=0;i<10;i++){            visit[i] = -1;        }        for(int i=0;i<str.length();i++){            dp[i] = 0;        }        visit[str.charAt(0)-'0'] = 0;        dp[0] = 1;        for(int i=1;i<str.length();i++){            int tmp = str.charAt(i)-'0';            if(visit[tmp]==-1){                dp[i] = dp[i-1]+1;                visit[tmp]=i;            }else{                if(last_start<=visit[tmp]){                    last_start = visit[tmp]+1;                    dp[i] = i-visit[tmp];                    visit[tmp] = i;                }else{                    dp[i] = dp[i-1]+1;                    visit[tmp] = i;                }            }            if(dp[i]>maxlen){                maxlen = dp[i];                maxindex = i+1-maxlen;            }        }        return str.substring(maxindex, maxlen+maxindex-1);    }

改进方法三:

/**     * noRepeatSubString2的优化     * @param str     * @return     */    private static String noRepeatSubString3(String str){        int visit[] = new int[10];        //记录到达i的最大子串的长度        int count = 1;        int last_start = 0;        int maxlen=0,maxindex=0;        for(int i=0;i<10;i++){            visit[i] = -1;        }        visit[str.charAt(0)-'0'] = 0;        for(int i=1;i<str.length();i++){            int tmp = str.charAt(i)-'0';            if(visit[tmp]==-1){                count++;                visit[tmp]=i;            }else{                if(last_start<=visit[tmp]){                    last_start = visit[tmp]+1;                    count = i-visit[tmp];                    visit[tmp] = i;                }            }            if(count>maxlen){                maxlen = count;                maxindex = i+1-maxlen;            }        }        return str.substring(maxindex, maxlen+maxindex-1);    }
原创粉丝点击