string S
of length N
文字を繰り返さずに最長のサブストリングを見つけます。
例:
入力: "stackoverflow"
出力: "stackoverfl"
そのような候補が2つある場合は、最初に左から戻ります。線形時間および定空間アルゴリズムが必要です。
各文字の情報を格納する文字列と配列の開始ロケーターと終了ロケーター(/ポインター)が必要になります。少なくとも1回は発生しましたか?
文字列の先頭から開始し、両方のロケーターが文字列の先頭を指します。
繰り返しが見つかるまで(または文字列の最後に到達するまで)、エンドロケーターを右に移動します。処理された各文字について、配列に格納します。これが最大の部分文字列である場合、停止時に位置を保存します。また、繰り返されるキャラクターを覚えておいてください。
ここで、開始ロケーターで同じことを行い、各文字を処理するときに、そのフラグを配列から削除します。繰り返し文字の以前の出現を見つけるまでロケーターを移動します。
文字列の最後に到達していない場合は、手順3に戻ります。
全体:O(N)
import Java.util.HashSet;
public class SubString {
public static String subString(String input){
HashSet<Character> set = new HashSet<Character>();
String longestOverAll = "";
String longestTillNow = "";
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (set.contains(c)) {
longestTillNow = "";
set.clear();
}
longestTillNow += c;
set.add(c);
if (longestTillNow.length() > longestOverAll.length()) {
longestOverAll = longestTillNow;
}
}
return longestOverAll;
}
public static void main(String[] args) {
String input = "substringfindout";
System.out.println(subString(input));
}
}
特定の文字が最後に発生した位置を示す配列を保持します。便宜上、すべての文字は-1の位置にあります。ウィンドウを保持している文字列を反復処理し、そのウィンドウで文字が繰り返される場合、この文字の最初の出現で終わるプレフィックスを切り取ります。全体を通して、最長の長さを維持します。 python実装:
def longest_unique_substr(S):
# This should be replaced by an array (size = alphabet size).
last_occurrence = {}
longest_len_so_far = 0
longest_pos_so_far = 0
curr_starting_pos = 0
curr_length = 0
for k, c in enumerate(S):
l = last_occurrence.get(c, -1)
# If no repetition within window, no problems.
if l < curr_starting_pos:
curr_length += 1
else:
# Check if it is the longest so far
if curr_length > longest_len_so_far:
longest_pos_so_far = curr_starting_pos
longest_len_so_far = curr_length
# Cut the prefix that has repetition
curr_length -= l - curr_starting_pos
curr_starting_pos = l + 1
# In any case, update last_occurrence
last_occurrence[c] = k
# Maybe the longest substring is a suffix
if curr_length > longest_len_so_far:
longest_pos_so_far = curr_starting_pos
longest_len_so_far = curr_length
return S[longest_pos_so_far:longest_pos_so_far + longest_len_so_far]
編集済み:
以下はコンセサスの実装です。それは私の最初の出版の後に私に起こりました。オリジナルを削除しないように、次のように表示されます。
public static String longestUniqueString(String S) {
int start = 0, end = 0, length = 0;
boolean bits[] = new boolean[256];
int x = 0, y = 0;
for (; x < S.length() && y < S.length() && length < S.length() - x; x++) {
bits[S.charAt(x)] = true;
for (y++; y < S.length() && !bits[S.charAt(y)]; y++) {
bits[S.charAt(y)] = true;
}
if (length < y - x) {
start = x;
end = y;
length = y - x;
}
while(y<S.length() && x<y && S.charAt(x) != S.charAt(y))
bits[S.charAt(x++)]=false;
}
return S.substring(start, end);
}//
元の投稿:
これが私の2セントです。テスト文字列が含まれています。 boolean bits [] = new boolean [256]は、より大きな文字セットを包含するために大きくなる場合があります。
public static String longestUniqueString(String S) {
int start=0, end=0, length=0;
boolean bits[] = new boolean[256];
int x=0, y=0;
for(;x<S.length() && y<S.length() && length < S.length()-x;x++) {
Arrays.fill(bits, false);
bits[S.charAt(x)]=true;
for(y=x+1;y<S.length() && !bits[S.charAt(y)];y++) {
bits[S.charAt(y)]=true;
}
if(length<y-x) {
start=x;
end=y;
length=y-x;
}
}
return S.substring(start,end);
}//
public static void main(String... args) {
String input[][] = { { "" }, { "a" }, { "ab" }, { "aab" }, { "abb" },
{ "aabc" }, { "abbc" }, { "aabbccdefgbc" },
{ "abcdeafghicabcdefghijklmnop" },
{ "abcdeafghicabcdefghijklmnopqrabcdx" },
{ "zxxaabcdeafghicabcdefghijklmnopqrabcdx" },
{"aaabcdefgaaa"}};
for (String[] a : input) {
System.out.format("%s *** GIVES *** {%s}%n", Arrays.toString(a),
longestUniqueString(a[0]));
}
}
文字列変数を2つだけ使用したもう1つのソリューションを次に示します。
public static String getLongestNonRepeatingString(String inputStr){
if(inputStr == null){
return null;
}
String maxStr = "";
String tempStr = "";
for(int i=0; i < inputStr.length(); i++){
// 1. if tempStr contains new character, then change tempStr
if(tempStr.contains("" + inputStr.charAt(i))){
tempStr = tempStr.substring(tempStr.lastIndexOf(inputStr.charAt(i)) + 1);
}
// 2. add new character
tempStr = tempStr + inputStr.charAt(i);
// 3. replace maxStr with tempStr if tempStr is longer
if(maxStr.length() < tempStr.length()){
maxStr = tempStr;
}
}
return maxStr;
}
インタビューで同じ質問をされました。
Pythonを記述しましたコード、すべての異なる文字を含む部分文字列の最初の出現を見つけます。私の実装では、index = 0で開始し、入力文字列を反復処理します。反復処理では、Python dict seems
を使用して、文字列のインデックスを入力文字列に格納しました。
繰り返しで、char c
がcurrent substringで見つからない場合– KeyError例外を発生させます
c
が現在のサブストリングで重複文字であることが判明した場合(c
が反復中に以前に出現したため–そのインデックスに名前を付けたlast_seen
)新しい部分文字列を開始します
def lds(string: str) -> str:
""" returns first longest distinct substring in input `string` """
seens = {}
start, end, curt_start = 0, 0, 0
for curt_end, c in enumerate(string):
try:
last_seen = seens[c]
if last_seen < curt_start:
raise KeyError(f"{c!r} not found in {string[curt_start: curt_end]!r}")
if end - start < curt_end - curt_start:
start, end = curt_start, curt_end
curt_start = last_seen + 1
except KeyError:
pass
seens[c] = curt_end
else:
# case when the longest substring is suffix of the string, here curt_end
# do not point to a repeating char hance included in the substring
if string and end - start < curt_end - curt_start + 1:
start, end = curt_start, curt_end + 1
return string[start: end]
別のO(n) JavaScriptソリューション。ループ中に文字列を変更しません。これまでの最長サブ文字列のオフセットと長さを追跡するだけです。
function longest(str) {
var hash = {}, start, end, bestStart, best;
start = end = bestStart = best = 0;
while (end < str.length) {
while (hash[str[end]]) hash[str[start++]] = 0;
hash[str[end]] = 1;
if (++end - start > best) bestStart = start, best = end - start;
}
return str.substr(bestStart, best);
}
// I/O for snippet
document.querySelector('input').addEventListener('input', function () {
document.querySelector('span').textContent = longest(this.value);
});
Enter Word:<input><br>
Longest: <span></span>
すべての部分文字列を1つずつ検討し、各部分文字列にすべての一意の文字が含まれているかどうかを確認できます。 n *(n + 1)/ 2個の部分文字列があります。 substirngにすべての一意の文字が含まれているかどうかは、左から右にスキャンし、訪問した文字のマップを保持することで線形時間で確認できます。このソリューションの時間の複雑さはO(n ^ 3)になります。
import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.HashMap;
import Java.util.LinkedHashSet;
import Java.util.List;
import Java.util.Map;
import Java.util.Set;
public class LengthOfLongestSubstringWithOutRepeatingChar {
public static void main(String[] args)
{
String s="stackoverflow";
//allSubString(s);
System.out.println("result of find"+find(s));
}
public static String find(String s)
{
List<String> allSubsring=allSubString(s);
Set<String> main =new LinkedHashSet<String>();
for(String temp:allSubsring)
{
boolean a = false;
for(int i=0;i<temp.length();i++)
{
for(int k=temp.length()-1;k>i;k--)
{
if(temp.charAt(k)==temp.charAt(i))
a=true;
}
}
if(!a)
{
main.add(temp);
}
}
/*for(String x:main)
{
System.out.println(x);
}*/
String res=null;
int min=0,max=s.length();
for(String temp:main)
{
if(temp.length()>min&&temp.length()<max)
{
min=temp.length();
res=temp;
}
}
System.out.println(min+"ha ha ha"+res+"he he he");
return res;
}
//substrings left to right ban rahi hai
private static List<String> allSubString(String str) {
List<String> all=new ArrayList<String>();
int c=0;
for (int i = 0; i < str.length(); i++) {
for (int j = 0; j <= i; j++) {
if (!all.contains(str.substring(j, i + 1)))
{
c++;
all.add(str.substring(j, i + 1));
}
}
}
for(String temp:all)
{
System.out.println("substring :-"+temp);
}
System.out.println("count"+c);
return all;
}
}
JavaScriptのアルゴリズム(多くのコメント付き).
/**
Given a string S find longest substring without repeating characters.
Example:
Input: "stackoverflow"
Output: "stackoverfl"
Input: "stackoverflowabcdefghijklmn"
Output: "owabcdefghijklmn"
*/
function findLongestNonRepeatingSubStr(input) {
var chars = input.split('');
var currChar;
var str = "";
var longestStr = "";
var hash = {};
for (var i = 0; i < chars.length; i++) {
currChar = chars[i];
if (!hash[chars[i]]) { // if hash doesn't have the char,
str += currChar; //add it to str
hash[chars[i]] = {index:i};//store the index of the char
} else {// if a duplicate char found..
//store the current longest non-repeating chars. until now
//In case of equal-length, <= right-most str, < will result in left most str
if(longestStr.length <= str.length) {
longestStr = str;
}
//Get the previous duplicate char's index
var prevDupeIndex = hash[currChar].index;
//Find all the chars AFTER previous duplicate char and current one
var strFromPrevDupe = input.substring(prevDupeIndex + 1, i);
//*NEW* longest string will be chars AFTER prevDupe till current char
str = strFromPrevDupe + currChar;
//console.log(str);
//Also, Reset hash to letters AFTER duplicate letter till current char
hash = {};
for (var j = prevDupeIndex + 1; j <= i; j++) {
hash[input.charAt(j)] = {index:j};
}
}
}
return longestStr.length > str.length ? longestStr : str;
}
//console.log("stackoverflow => " + findLongestNonRepeatingSubStr("stackoverflow"));
//returns stackoverfl
//console.log("stackoverflowabcdefghijklmn => " +
findLongestNonRepeatingSubStr("stackoverflowabcdefghijklmn")); //returns owabcdefghijklmn
//console.log("1230123450101 => " + findLongestNonRepeatingSubStr("1230123450101")); //
returns 234501
Pythonで文字を繰り返しない最長の部分文字列
public int lengthOfLongestSubstring(String s) {
if(s.equals(""))
return 0;
String[] arr = s.split("");
HashMap<String,Integer> map = new HashMap<>();
Queue<String> q = new LinkedList<>();
int l_till = 1;
int l_all = 1;
map.put(arr[0],0);
q.add(arr[0]);
for(int i = 1; i < s.length(); i++){
if (map.containsKey(arr[i])) {
if(l_till > l_all){
l_all = l_till;
}
while(!q.isEmpty() && !q.peek().equals(arr[i])){
map.remove(q.remove());
}
if(!q.isEmpty())
map.remove(q.remove());
q.add(arr[i]);
map.put(arr[i],i);
//System.out.println(q);
//System.out.println(map);
l_till = q.size();
}
else {
l_till = l_till + 1;
map.put(arr[i],i);
q.add(arr[i]);
}
}
if(l_till > l_all){
l_all = l_till;
}
return l_all;
}
import Java.util.HashMap;
import Java.util.HashSet;
public class SubString {
public static String subString(String input) {
String longesTillNOw = "";
String longestOverAll = "";
HashMap<Character,Integer> chars = new HashMap<>();
char[] array=input.toCharArray();
int start=0;
for (int i = 0; i < array.length; i++) {
char charactor = array[i];
if (chars.containsKey(charactor) ) {
start=chars.get(charactor)+1;
i=start;
chars.clear();
longesTillNOw = "";
} else {
chars.put(charactor,i);
longesTillNOw = longesTillNOw + charactor;
if (longesTillNOw.length() > longestOverAll.length()) {
longestOverAll = longesTillNOw;
}
}
}
return longestOverAll;
}
public static void main(String[] args) {
String input = "stackoverflowabcdefghijklmn";
System.out.println(subString(input));
}
}
質問:文字を繰り返さずに最長のサブストリングを見つけます。例1:
import Java.util.LinkedHashMap;
import Java.util.Map;
public class example1 {
public static void main(String[] args) {
String a = "abcabcbb";
// output => 3
System.out.println( lengthOfLongestSubstring(a));
}
private static int lengthOfLongestSubstring(String a) {
if(a == null || a.length() == 0) {return 0 ;}
int res = 0 ;
Map<Character , Integer> map = new LinkedHashMap<>();
for (int i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
if (!map.containsKey(ch)) {
//If ch is not present in map, adding ch into map along with its position
map.put(ch, i);
}else {
/*
If char ch is present in Map, reposition the cursor i to the position of ch and clear the Map.
*/
i = map.put(ch, i);// updation of index
map.clear();
}//else
res = Math.max(res, map.size());
}
return res;
}
}
出力として繰り返し文字のない最長の文字列が必要な場合は、forループ内でこれを実行します。
String res ="";// global
int len = 0 ;//global
if(len < map.size()) {
len = map.size();
res = map.keySet().toString();
}
System.out.println("len -> " + len);
System.out.println("res => " + res);
これが私の解決策であり、leetcodeに受け入れられました。しかし、統計を見た後、ソリューション全体の結果がはるかに速いことがわかりました....つまり、私のソリューションはすべてのテストケースで約600ミリ秒であり、jsソリューションのほとんどは約200-300ミリ秒ブラケットです私の解決策が遅い理由を教えてくださいwww ??
var lengthOfLongestSubstring = function(s) {
var arr = s.split("");
if (s.length === 0 || s.length === 1) {
return s.length;
}
var head = 0,
tail = 1;
var str = arr[head];
var maxL = 0;
while (tail < arr.length) {
if (str.indexOf(arr[tail]) == -1) {
str += arr[tail];
maxL = Math.max(maxL, str.length);
tail++;
} else {
maxL = Math.max(maxL, str.length);
head = head + str.indexOf(arr[tail]) + 1;
str = arr[head];
tail = head + 1;
}
}
return maxL;
};
import Java.util.ArrayList;
import Java.util.HashSet;
import Java.util.LinkedHashSet;
import Java.util.List;
import Java.util.Set;
import Java.util.TreeMap;
public class LongestSubString2 {
public static void main(String[] args) {
String input = "stackoverflowabcdefghijklmn";
List<String> allOutPuts = new ArrayList<String>();
TreeMap<Integer, Set> map = new TreeMap<Integer, Set>();
for (int k = 0; k < input.length(); k++) {
String input1 = input.substring(k);
String longestSubString = getLongestSubString(input1);
allOutPuts.add(longestSubString);
}
for (String str : allOutPuts) {
int strLen = str.length();
if (map.containsKey(strLen)) {
Set set2 = (HashSet) map.get(strLen);
set2.add(str);
map.put(strLen, set2);
} else {
Set set1 = new HashSet();
set1.add(str);
map.put(strLen, set1);
}
}
System.out.println(map.lastKey());
System.out.println(map.get(map.lastKey()));
}
private static void printArray(Object[] currentObjArr) {
for (Object obj : currentObjArr) {
char str = (char) obj;
System.out.println(str);
}
}
private static String getLongestSubString(String input) {
Set<Character> set = new LinkedHashSet<Character>();
String longestString = "";
int len = input.length();
for (int i = 0; i < len; i++) {
char currentChar = input.charAt(i);
boolean isCharAdded = set.add(currentChar);
if (isCharAdded) {
if (i == len - 1) {
String currentStr = getStringFromSet(set);
if (currentStr.length() > longestString.length()) {
longestString = currentStr;
}
}
continue;
} else {
String currentStr = getStringFromSet(set);
if (currentStr.length() > longestString.length()) {
longestString = currentStr;
}
set = new LinkedHashSet<Character>(input.charAt(i));
}
}
return longestString;
}
private static String getStringFromSet(Set<Character> set) {
Object[] charArr = set.toArray();
StringBuffer strBuff = new StringBuffer();
for (Object obj : charArr) {
strBuff.append(obj);
}
return strBuff.toString();
}
}
def max_substring(string):
last_substring = ''
max_substring = ''
for x in string:
k = find_index(x,last_substring)
last_substring = last_substring[(k+1):]+x
if len(last_substring) > len(max_substring):
max_substring = last_substring
return max_substring
def find_index(x, lst):
k = 0
while k <len(lst):
if lst[k] == x:
return k
k +=1
return -1
function longestSubstringWithoutDuplication(str) {
var max = 0;
//if empty string
if (str.length === 0){
return 0;
} else if (str.length === 1){ //case if the string's length is 1
return 1;
}
//loop over all the chars in the strings
var currentChar,
map = {},
counter = 0; //count the number of char in each substring without duplications
for (var i=0; i< str.length ; i++){
currentChar = str.charAt(i);
//if the current char is not in the map
if (map[currentChar] == undefined){
//Push the currentChar to the map
map[currentChar] = i;
if (Object.keys(map).length > max){
max = Object.keys(map).length;
}
} else { //there is duplacation
//update the max
if (Object.keys(map).length > max){
max = Object.keys(map).length;
}
counter = 0; //initilize the counter to count next substring
i = map[currentChar]; //start from the duplicated char
map = {}; // clean the map
}
}
return max;
}
Cのソリューション.
#include<stdio.h>
#include <string.h>
void longstr(char* a, int *start, int *last)
{
*start = *last = 0;
int visited[256];
for (int i = 0; i < 256; i++)
{
visited[i] = -1;
}
int max_len = 0;
int cur_len = 0;
int prev_index;
visited[a[0]] = 0;
for (int i = 1; i < strlen(a); i++)
{
prev_index = visited[a[i]];
if (prev_index == -1 || i - cur_len > prev_index)
{
cur_len++;
*last = i;
}
else
{
if (max_len < cur_len)
{
*start = *last - cur_len;
max_len = cur_len;
}
cur_len = i - prev_index;
}
visited[a[i]] = i;
}
if (max_len < cur_len)
{
*start = *last - cur_len;
max_len = cur_len;
}
}
int main()
{
char str[] = "ABDEFGABEF";
printf("The input string is %s \n", str);
int start, last;
longstr(str, &start, &last);
//printf("\n %d %d \n", start, last);
memmove(str, (str + start), last - start);
str[last] = '\0';
printf("the longest non-repeating character substring is %s", str);
return 0;
}
このようなものを使用できますか。
def longestpalindrome(str1):
arr1=list(str1)
s=set(arr1)
arr2=list(s)
return len(arr2)
str1='abadef'
a=longestpalindrome(str1)
print(a)
部分文字列の長さのみが返される場合
ソリューションを修正して、「文字を繰り返さずに最長のサブストリングの長さを見つける」ようにしました。
public string LengthOfLongestSubstring(string s) {
var res = 0;
var dict = new Dictionary<char, int>();
var start = 0;
for(int i =0; i< s.Length; i++)
{
if(dict.ContainsKey(s[i]))
{
start = Math.Max(start, dict[s[i]] + 1); //update start index
dict[s[i]] = i;
}
else
{
dict.Add(s[i], i);
}
res = Math.Max(res, i - start + 1); //track max length
}
return s.Substring(start,res);
}
最適化されていませんが、Pythonの簡単な答え
def lengthOfLongestSubstring(s):
temp,maxlen,newstart = {},0,0
for i,x in enumerate(s):
if x in temp:
newstart = max(newstart,s[:i].rfind(x)+1)
else:
temp[x] = 1
maxlen = max(maxlen, len(s[newstart:i + 1]))
return maxlen
費用のかかる問題はrfind
であると思うので、完全には最適化されていません。
テスト済みで動作しています。わかりやすくするために、文字を入れるための引き出しがあると思います。
public int lengthOfLongestSubstring(String s) {
int maxlen = 0;
int start = 0;
int end = 0;
HashSet<Character> drawer = new HashSet<Character>();
for (int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
if (drawer.contains(ch)) {
//search for ch between start and end
while (s.charAt(start)!=ch) {
//drop letter from drawer
drawer.remove(s.charAt(start));
start++;
}
//Do not remove from drawer actual char (it's the new recently found)
start++;
end++;
}
else {
drawer.add(ch);
end++;
int _maxlen = end-start;
if (_maxlen>maxlen) {
maxlen=_maxlen;
}
}
}
return maxlen;
}
アルゴリズム:
1)空の辞書を初期化しますdct文字列に文字が既に存在するかどうかを確認します。
2)cnt-文字を繰り返しずにサブストリングのカウントを保持します。
3)lおよびrは、文字列の最初のインデックスに初期化される2つのポインターです。
4)文字列の各文字をループします。
5)dctに文字が存在しない場合は、追加して、cntを増やします。
6)既に存在する場合は、cntがresStrLenよりも大きいかどうかを確認します。
7)dctから文字を削除し、左のポインターを1だけシフトし、カウントを減らします。
8)l、r入力文字列の長さ以上になるまで、5,6,7を繰り返します。
9)繰り返しのない文字を含む入力文字列などのケースを処理するために、最後にもう1つチェックします。
これは単純なpythonプログラム繰り返し文字なしで最長の部分文字列を見つける=
a="stackoverflow"
strLength = len(a)
dct={}
resStrLen=0
cnt=0
l=0
r=0
strb=l
stre=l
while(l<strLength and r<strLength):
if a[l] in dct:
if cnt>resStrLen:
resStrLen=cnt
strb=r
stre=l
dct.pop(a[r])
cnt=cnt-1
r+=1
else:
cnt+=1
dct[a[l]]=1
l+=1
if cnt>resStrLen:
resStrLen=cnt
strb=r
stre=l
print "Result String Length : "+str(resStrLen)
print "Result String : " + a[strb:stre]
同様の種類のソリューションをJavaで実装しました。文字列全体ではなく、文字列の長さを返しています。
参照用のソリューションを以下で見つけてください。
public int getLengthOfLongestSubstring(String input) {
char[] chars = input.toCharArray();
String longestString = "";
String oldString="";
for(int i= 0; i < chars.length;i++) {
if (longestString.contains(String.valueOf(chars[i])))
{
if(longestString.length() > oldString.length()){
oldString = longestString;
}
if(longestString.split(String.valueOf(chars[i])).length>1)
longestString= longestString.split(String.valueOf(chars[i]))[1]+(chars[i]);
else{
longestString =String.valueOf(chars[i]);
}
}
else{
longestString =longestString+chars[i];
}
}
return oldString.length()< longestString.length()? longestString.length(): oldString.length();
}
または、次のリンクを参照として使用できます。
この問題は、O(n)時間の複雑さで解決できます。3つの変数を初期化します
手順:文字列を反復処理し、次のアクションを実行します。
現在の文字がハッシュマップに存在する場合、
a)開始インデックスが、文字(以前にアクセスした同じ文字の最後のインデックス)に対するハッシュマップに存在する値以下かどうかを確認します。
b)少ない場合、開始変数値をハッシュマップの値+ 1(以前にアクセスした同じ文字の最後のインデックス+ 1)として割り当てます。
c)ハッシュマップの現在の文字の値を文字の現在のインデックスとしてオーバーライドすることにより、ハッシュマップを更新します。
d)end-startを最長の部分文字列値として計算し、それが以前の最長の非繰り返し部分文字列より大きい場合は更新します。
以下は、この問題に対するJavascriptソリューションです。
var lengthOfLongestSubstring = function(s) {
let length = s.length;
let ans = 0;
let start = 0,
end = 0;
let hashMap = {};
for (var i = 0; i < length; i++) {
if (!hashMap.hasOwnProperty(s[i])) {
hashMap[s[i]] = i;
} else {
if (start <= hashMap[s[i]]) {
start = hashMap[s[i]] + 1;
}
hashMap[s[i]] = i;
}
end++;
ans = ans > (end - start) ? ans : (end - start);
}
return ans;
};
シンプルで簡単
import Java.util.Scanner;
public class longestsub {
static Scanner sn = new Scanner(System.in);
static String Word = sn.nextLine();
public static void main(String[] args) {
System.out.println("The Length is " +check(Word));
}
private static int check(String Word) {
String store="";
for (int i = 0; i < Word.length(); i++) {
if (store.indexOf(Word.charAt(i))<0) {
store = store+Word.charAt(i);
}
}
System.out.println("Result Word " +store);
return store.length();
}
}
public int lengthOfLongestSubstring(String s) {
int startIndex = 0;
int maxLength = 0;
//since we have 256 ascii chars
int[] lst = new int[256];
Arrays.fill(lst,-1);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
//to get ascii value of c
int ic = (int) c;
int value = lst[ic];
//this will say to move start index to next index of the repeating char
//we only do this if the repeating char index is greater than start index
if (value >= startIndex) {
maxLength = Math.max(maxLength, i - startIndex);
startIndex = value + 1;
}
lst[ic] = i;
}
//when we came to an end of string
return Math.max(maxLength,s.length()-startIndex);
}
これは最速であり、線形時間と一定の空間です
O(n ^ 2)をpython。
私のコード:
def main():
test='stackoverflow'
tempstr=''
maxlen,index=0,0
indexsubstring=''
print 'Original string is =%s\n\n' %test
while(index!=len(test)):
for char in test[index:]:
if char not in tempstr:
tempstr+=char
if len(tempstr)> len(indexsubstring):
indexsubstring=tempstr
Elif (len(tempstr)>=maxlen):
maxlen=len(tempstr)
indexsubstring=tempstr
break
tempstr=''
print 'max substring length till iteration with starting index =%s is %s'%(test[index],indexsubstring)
index+=1
if __name__=='__main__':
main()
これは私のjavascriptとcppの実装の詳細です。 https://algorithm.pingzhang.io/String/longest_substring_without_repeating_characters.html
文字を繰り返すことなく、最も長い部分文字列を見つけたい。最初に思い浮かぶのは、すべての文字を部分文字列に格納するハッシュテーブルが必要なため、新しい文字が入ったときに、この文字が既に部分文字列にあるかどうかを簡単に確認できることです。 valueIdxHash
と呼びます。次に、サブストリングにはstartIdx
とendIdx
があります。したがって、部分文字列の開始インデックスを追跡する変数が必要であり、startIdx
と呼びます。インデックスi
にあり、すでにサブストリング(startIdx, i - 1)
があるとします。次に、この部分文字列が成長し続けるかどうかを確認します。
valueIdxHash
にstr[i]
が含まれる場合、それは繰り返し文字であることを意味します。ただし、この繰り返し文字がサブストリング(startIdx, i - 1)
にあるかどうかを確認する必要があります。したがって、前回表示されたstr[i]
のインデックスを取得し、このインデックスをstartIdx
と比較する必要があります。
startIdx
の方が大きい場合、最後に出現したstr[i]
は、サブストリングのoutsideであることを意味します。したがって、サブトリングは成長し続けることができます。startIdx
の方が小さい場合、最後に現れたstr[i]
がサブストリングのwithinであることを意味します。したがって、部分文字列はこれ以上成長できません。 startIdx
はvalueIdxHash[str[i]] + 1
として更新され、新しいサブストリング(valueIdxHash[str[i]] + 1, i)
は成長し続ける可能性があります。valueIdxHash
にstr[i]
が含まれていない場合、サブストリングは大きくなり続ける可能性があります。