1. 程式人生 > >求最大不重複子串(Java)

求最大不重複子串(Java)

一個經典問題,就是求字串中不包含重複字元的最大子串。如果有多個這樣的子串,則輸出第一個。例:str=”abxacsvada”,最大不重複子串為:“bxacsv”。
我的思路其實也就是從頭比較到尾來找,只是中間加了一些判斷條件進行了優化。具體流程(先轉化成char[] ch):
1、假設該最長子串的首字元為ch [i] (0<=i< ch.length),則找到ch[i]==ch[j] (i< j< ch.length).此時”j”也就確定了該子串有可能的最大長度了。
2、進一步確定該子串的長度,也就是要確定從ch[i]起,“j”長度的子串裡有沒有重複的字元,為了區分,這裡定義int value=j。確認是否有ch[i+1]==ch[j] (i+1< j< value)。如果有,則進一步確定子串長度,再把此時的”j”賦值給value。
3、重複上訴2步驟直到“i+n”==value.此時的value也就是以ch[i]為起點的最大不重複子串的長度值。
程式碼如下:

import java.util.Scanner;
public class Main {

    static String calDuplicateString(String str) {//分別以0-ch.length的字元為首字元尋找最大不重複子串
        char[] ch=str.toCharArray();//轉化成char陣列
        int max=0;//記錄最大不重複子串的長度
        int value;//記錄以ch[i]為首字元的最大不重複子串的長度
        int k=0;//記錄最大不重複子串的起始下標
        for(int i=0;i<ch.length;i++){//i表示起始字元的下標
if((i-1)<(max+k) && i>0 && ch[i-1]!=ch[max+k])//優化演算法① continue; value=search(ch,i,max+k);//以ch[i]為首字元,尋找最大不重複子串,返回長度 if(max<value){//如果此時得到的長度比原來得到的長度長,那就賦值給max,並且記錄下此時的首字元下標 max=value; k=i; } if
(max>=ch.length-i-1)//優化演算法② break; } return new String(ch,k,max);//返回該最大子串 } //該方法為了尋找以ch[head]為起始字元的最大子串,其中head表示起始字元的下標,left表示最開始需要比較的起始位置 static int search(char[] ch,int head, int left) { int m=ch.length;//表示最大子串的最後一個字元的下標 //上面思路對應的程式碼就是這裡 for(int i=head;i<m-1;i++)③ for(int j=left;j<m;j++) if(ch[i]==ch[j]){//一旦出現相同字元,則後面的字元都不可能是該最大子串的了 m=j; break; } return m-head;//返回最大子串的長度 } //main函式測試 public static void main(String[] args){ Scanner in = new Scanner(System.in); String _str; _str = in.nextLine(); System.out.println(calDuplicateString(_str)); } }

原始思路就是暴力解法,中間我加了兩步優化,其實嚴格算三步。程式碼中標號處為優化的地方,逐一解釋:
①:假設String str=”abcdbacdjas”。當第一次尋找以第一個字元為首字元的最長子串時,找的最長子串為“abcd”,此時我們尋找以第二個字元為首字元的最大子串,分析一下:
對於第一次找到的結果來看,前四個字元是沒有重複字元的,並且說明第五個字元肯定與前四個字元中的某一個相同(不考慮到末尾的情況)。當且僅當第一個字元等於第五個字元時,第二個字元為首字元的最大子串的長度才有可能大於等於第一次找到的最大子串。因為如果ch[0]!=ch[4],那麼肯定存在ch[i](0< i <4)==ch[4]。所以以第二個字元為首字元的最大子串的長度不可能大於3了。所以得出三個判斷條件:
(i-1)<(max+k) && i>0 && ch[i-1]!=ch[max+k]
i>0:因為第一次時沒有前面得出的最大子串。

ch[i-1]!=ch[max+k]:也就是上面分析得出的判斷式

(i-1)<(max+k):例如上面,所有分析都是比較前面得出的最大子串與第五個字元是否相等,那麼顯然不能比較大於第五個字元後的字元了。不然如果一直沒有尋找到大於原來的最大子串的最大子串,那麼max+k始終不變,而i-1已經>=max+k了,這樣就會continue掉很多不該continue的地方。

②:max>=ch.length-i-1:這個好理解,就是尋找以ch[i]為首字元的最大子串時,如果ch[i]加上它後面的所有字元如果都不能大於之前得到最大子串的長度max時,那麼,後面的這些字元都沒有去尋找的必要了。

③:這裡是縮小了兩個迴圈的範圍,假設:在尋找以第一個字元為首字元的最大子串時,因為不知道最開始有多長,所以需要設為ch.length,如果此時找到ch[0]==ch[5],那麼此時最大子串的長度就<=5了,所以此時還需要判斷ch[1]到ch[4]裡有沒有重複字元就可以了。而left是根據上一次得出的最大子串來確定的,上面已經①中分析過了。

上面程式碼有可能還存在bug,畢竟我沒有把所有特殊情況都測試一遍。

相關推薦

重複Java

一個經典問題,就是求字串中不包含重複字元的最大子串。如果有多個這樣的子串,則輸出第一個。例:str=”abxacsvada”,最大不重複子串為:“bxacsv”。 我的思路其實也就是從頭比較到尾來找,只是中間加了一些判斷條件進行了優化。具體流程(先轉化成cha

重複---LeetCode3

Longest Substring Without Repeating Characters 題目描述 Given a string, find the length of the longest substring without repeating characters. Exa

找出字串重複或者是列表

# 找出來一個字串中最長不重複子串def find_Maxlen_Son_list(astr): maxlen = 0 定義最長字串的初始長度// dict = {} list1 = [] for i in range(0,len(astr)): str2 = ''

字串的重複java

  -暴力法    兩個指標實現,複雜度O(n^2) package test; import java.util.Scanner; public class Main2 { public static String maxRepat(String str)

LeetCode 3 重複

找出最大不重複子串 關鍵在於利用雜湊表的查詢優勢,設定一個記錄不重複字串的開始位置。需要線性時間 public class Solution {     public int LengthOfLon

回文Manacher演算法

這個知識點我第一天聽時,完全不懂,後來慢慢的看一個pdf文件和請教一個學長才有點懂得,到今天我繼續看一篇部落格,才對最大回文子串有清晰的理解,所以上面有什麼不對的請給位積極指出。 求最大回文子串,我個人覺得其實就是一種想法(它用到了動態規劃的思想),還不算一種單獨的演算法。

Manacher演算法------長迴文Java)

最長迴文子串 對於一個字串,請設計一個高效演算法,計算其中最長迴文子串的長度。 給定字串A以及它的長度n,請返回最長迴文子串的長度。 測試樣例: "abc1234321ab",12 返回:7 public class Main {      public st

找出兩個字串中的公共java實現

import java.util.HashSet; import java.util.Set; public class Test { public static void main(String[] args) { String

LeetCode千題斬之3:Longest Substring Without Repeating Characters重複

題目:Given a string, find the length of the longest substring without repeating characters. 先說說思路,優化的方法在於用一個滑動的視窗[i,j]瀏覽字串,先把遇到的字元加入一個字典dic

重複重複 思路

題目: 求任意一個字串中的所有最長重複字串和所有最長不重複子串 最長不重複子串的解法:        設定一個輔助資料結構(如map)記錄每個字元最後一次出現的位置;遍歷字串中的每個字元,如果在map

尋找一個字串中的重複字尾陣列&找出一個字串中重複

一、尋找一個字串中的最長重複子串(字尾陣列) 字尾陣列其實可以看尋找一個字串中的最長重複子串(字尾陣列)作一個由字串s倒數i個字元組成的子串的集合,其中0<i<s.length(),例如 字串strstr的字尾陣列為: {r,tr,str,rstr,trstr,

字串中的重複

題目描述: 給定一字串只包含數字,請寫一個演算法,找出該字串中的最長不重複子串(不重複是指子串中每一元素不同於子串中其他元素) 如:“120135435”最長不重複子串為 “201354”

字串中的,重複--java程式碼

package ali; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.TreeMap; p

【BZOJ】4032: [HEOI2015]公共LibreOJ #2123

後綴 blog clas 字母 小寫 算法 存在 識別 題意 【題意】給兩個小寫字母串A,B,請你計算: (1) A的一個最短的子串,它不是B的子串 (2) A的一個最短的子串,它不是B的子序列 (3) A的一個最短的子序列,它不是B的子串 (4) A的一個最短的子序列,它

重疊

AR eating osi 說明 前綴 cas d+ join 不能 A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the

位元組跳動2018.9.9筆試 重複

題目描述 給定一個字串,請找出其中無重複字元的最長子字串的長度。例如,“abcabcbb”,其無重複字元的最長子字串實“abc”,其長度為3。“bbbbb”,其無重複字元的最長子字串是“b”,長度為1。 此題是leetcode第三題原題。 本人思路 以上圖為例

字串中重複長迴文演算法

一) 這裡用GOLANG實現了一個查詢最長不重複子串的演算法,在暴力查詢的基礎上作了優化,雖然速度還是比較慢,但是有助於理解後邊高階的演算法,值得一記。 暴力查詢的優化思路: 1)如果我們已經查詢到的最大子串長度比剩下沒有for到的子串還長,那最大子串不可能會在發生改變了

重複(精簡)

直接甩出程式碼吧,有問題可以交流討論,有O(n)的解法,有興趣小夥伴的可以自行了解。 //動態規劃的演算法求解( 時間複雜度是O(n^2) ) #include #include #include using namespace std; int main(){ char a[20]=

python實現找出來一個字串中重複

剛結束的一個筆試題,很簡單,不多說簡單貼一下具體的實現: #!usr/bin/env python #encoding:utf-8 ''' __Author__:沂水寒城 功能:找出來一個字串中最長不重複子串 ''' def find_longest_no_repe

長迴文多種解法

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest