一つ、タイトル説明
文字列を考えると、文字を繰り返すことなく、最長の部分文字列の長さを見つけます。
繰り返される文字列を考えると含まない識別する最長のサブストリングの長さを。
実施例1:
入力:「abcabcbb」
出力:3
説明:答えは3の長さと、「ABC」である
実施例2:
入力:「BBBBB」
出力:1
説明:答えが「B」であり、の長さ1.
例3:
入力:「pwwkew」
出力:3
説明:答えは「WKE」、3の長さの
ノート答えはサブ、「pwke」でなければならないことは、サブシーケンスとない部分文字列です。
第二に、問題解決のためのアイデア
一見、すべてが暴力です。暴力行為によって、それは非常に簡単な解決策になることができますが、時間の複雑さが相対的に高くなっています。私は、JavaのHashMapで使用することを選択し、ダブルループのために、第一層のループは、各I ++のために、I + 1番目に使用されるi番目の文字のマップの値を防ぐために、新しいHashMapのメモリ空間を作成したら、マップ文字が影響を受けます。操作の第二層はさらにサイクルがそうでない文字がマップに追加された場合、第2層目のサイクルから外れている場合、および、この文字のHashMapがあるかどうかを決定することで、マップのサイズと文字の最大数比較の数、大きな割り当て。
第二の方法は、時間の複雑さは、それを文字はHashSetのない場合は、HashSetのに格納された文字の位置を表す文字列の位置を制御するためのO(2N)と、2つのint型の変数の定義、あります、HashSetのは添字Iを指摘文字を削除し、私は長さを最大++そうであれば、添加した:限り値がMAXNUM HashSetのより大きいとして、初期値MAXNUM = 0を設定している与えるMAXNUM、最終的なリターンMAXNUM意志値。
第三の方法は、スライディングウィンドウアルゴリズムの改良。HashMapを使用する方法、および下付き文字は、現在の文字を識別するために、iとJJの添字を2つの変数を設定しリンクしました。私は文字の下付き文字を繰り返し識別するために使用される添字。J-I + 1は、文字列の長さを取得するために使用されるで繰り返されていません。ハッシュマップの文字があり、その後、あなたが私は再びこの文字比較ではHashMapの添字を取得した場合、大きい方を選択してください。(出現アバが発生することで、あなたが大きな値を選択しない場合の最後の文字、インデックス0の繰り返し文字、と私は2の値を持つ場合、エラーが4になりますので、結果は逆2が横断文字までハッシュマップ内の文字に付加されて表示されます。
ストレージアレイを有する第四の方法。文字は、0から256までのすべてのASCIIコードを表すので。文字を表す添字は、インデックスの値は、最新のインデックスに格納された値は、繰り返し文字になり、重複した文字があると仮定すると、文字列の位置に格納されます。長い文字列を横断するには、この時点での最新の買収下付き文字とリピート場所などとして、それを計算することができる長さの文字を繰り返さない、最大値を得ることができます。
第三に、コードの実装
package com.acm.Secondmonth;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class LetCode003 {
/**
* 返回:最长没有重复字符的个数
* 先用暴力法
* 直接二重循环 对第一层循环的每一个值度找一下不重复字符串个数
* @param s
* @return
*/
public static int lengthOfLongestSubstring(String s) {
if(s == null) {
throw new RuntimeException("invaild input:S is null");
}
int max = 0;
for(int i=0 ; i<s.length() && s.length()-i>=max ; i++) {
Map<Character , Integer> result = new HashMap<>();
for(int j=i ; j<s.length() ; j++) {
if(result.containsKey(s.charAt(j))) {
break;
}else {
result.put(s.charAt(j), j);
}
if(result.size() > max) {
max = result.size();
}
}
}
return max;
}
/**
*
* @param s
* @return
* 时间复杂度 O(2n)
* 每发现一个重复的字符就将一开始的字符删除 ,一直到将与其重复的字符和其前面的全部删除
*/
public static int lengthOfLongestSubstring01(String s) {
if(s == null) {
throw new RuntimeException("invaild input:S is null");
}
Set<Character> result = new HashSet<>();
int i=0 , j=0 , maxNum = 0;
while(i < s.length() && j < s.length()) {
if(!result.contains(s.charAt(j))) {
result.add(s.charAt(j++));
if(result.size() > maxNum) {
maxNum = result.size();
}
}else {
result.remove(s.charAt(i++));
}
}
return maxNum;
}
public static int lengthOfLongestSubstring03(String s ) {
if(s == null) {
throw new RuntimeException("invaild input:S is null");
}
int maxNum = 0;
Map<Character, Integer> result = new HashMap<>();
int start = 0 ; int end = 0;
while(end < s.length()) {
if(result.containsKey(s.charAt(end))) {
start = Math.max(result.get(s.charAt(end))+1 , start);
}
result.put(s.charAt(end), end);
maxNum = Math.max(maxNum, end-start+1);
end++;
}
return maxNum;
}
public static int lengthOfLongestSubstring04(String s) {
if(s == null) {
throw new RuntimeException("invaild input:S is null");
}
int maxNum = 0;
int[] result =new int[256];
for(int i=0 , j=0 ; j<s.length() ; j++) {
i = Math.max(result[s.charAt(j)], i);
maxNum = Math.max(maxNum , j-i+1);
result[s.charAt(j)] = j+1;
}
return maxNum;
}
public static void main(String[] args) {
test01();
test02();
test03();
test04();
}
private static void test01() {
String test = "abcabcbb";
System.out.println(lengthOfLongestSubstring(test));
System.out.println(lengthOfLongestSubstring01(test));
System.out.println(lengthOfLongestSubstring03(test));
System.out.println(lengthOfLongestSubstring04(test));
}
private static void test02() {
String test = "abba";
System.out.println(lengthOfLongestSubstring(test));
System.out.println(lengthOfLongestSubstring01(test));
System.out.println(lengthOfLongestSubstring03(test));
System.out.println(lengthOfLongestSubstring04(test));
}
private static void test03() {
String test = "pwwkew";
System.out.println(lengthOfLongestSubstring(test));
System.out.println(lengthOfLongestSubstring01(test));
System.out.println(lengthOfLongestSubstring03(test));
System.out.println(lengthOfLongestSubstring04(test));
}
private static void test04() {
String test = " ";
System.out.println(lengthOfLongestSubstring(test));
System.out.println(lengthOfLongestSubstring01(test));
System.out.println(lengthOfLongestSubstring03(test));
System.out.println(lengthOfLongestSubstring04(test));
}
}