找到最长的子字符串而不重复字符

时间:2012-03-16 09:11:16

标签: string algorithm

string S length N {{1}}找到最长的子字符串而不重复字符。

示例:

输入:“stackoverflow”

输出:“stackoverfl”

如果有两个这样的候选人,请先从左边返回。我需要线性时间和恒定空间算法。

37 个答案:

答案 0 :(得分:30)

  1. 您将需要一个开始和结束定位器(/指针) 字符串和存储每个字符信息的数组: 它至少出现过一次吗?

  2. 从字符串的开头开始,两个定位器都指向 字符串的开头。

  3. 将结束定位器向右移动直至找到 重复(或到达字符串的末尾)。对于每个已处理的字符,将其存储在数组中。 如果这是最大的子字符串,则停止存储位置。还要记住重复的角色。

  4. 现在,在处理时,使用start locator执行相同的操作 每个字符,从数组中删除它的标志。移动定位器直到 你会发现重复字符的早期出现。

  5. 如果尚未到达字符串末尾,请返回步骤3.

  6. 总体而言:O(N)

答案 1 :(得分:8)

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));
    }
}

答案 2 :(得分:5)

您保留一个数组,指示某个字符最后出现的位置。为方便起见,所有字符都出现在-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]

答案 3 :(得分:2)

编辑:

以下是concesus的实现。我最初的出版后发生在我身上。为了不删除原文,它显示如下:

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);
}//

原始邮件:

这是我的两分钱。包括测试字符串。 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]));
    }
}

答案 4 :(得分:2)

这是另外一个只有2个字符串变量的解决方案:

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;
}

答案 5 :(得分:1)

最长的子字符串,无需在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;
}

答案 6 :(得分:1)

enter image description here 简单的python片段 l =长度p =位置 maxl = maxlength maxp = maxposition

答案 7 :(得分:1)

另一个 O(n) JavaScript解决方案。它在循环期间不会改变字符串;它只是跟踪到目前为止最长子字符串的偏移量和长度:

&#13;
&#13;
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);
});
&#13;
Enter word:<input><br>
Longest: <span></span>
&#13;
&#13;
&#13;

答案 8 :(得分:1)

在一次采访中有人问我同样的问题。

我已经编写了Python 3 代码,以查找具有所有不同字符的子字符串的首次出现。在我的实现中,我从index = 0开始并遍历输入字符串。在迭代过程中,使用Python字典seems在输入字符串中存储字符索引,这些字符在迭代中已被访问过。

在迭代中,如果char c不在当前子字符串中找到–引发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]

答案 9 :(得分:1)

  

我们可以逐个考虑所有子字符串并检查每个子字符串是否包含所有唯一字符。   将有n *(n + 1)/ 2个子串。是否包含所有唯一字符的子项可以在线性时间内检查   从左到右扫描并保留访问过的角色的地图。该解决方案的时间复杂度为O(n ^ 3).`

&#13;
&#13;
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;
}
}
&#13;
&#13;
&#13;

答案 10 :(得分:1)

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

答案 11 :(得分:0)

# Create UUID 
python -c 'import uuid; print str(uuid.uuid1())'

# Create random UUID
python -c 'import uuid; print str(uuid.uuid4())'

答案 12 :(得分:0)

我还解决了这个问题,下面是我用JavaScript(Brute Force和Sliding Window)+ YouTube视频编写的两个解决方案,上面有解释https://youtu.be/1NzWlRP3yfI

/**
 * @param {string} s
 * @return {number}
 */

// //BRUTE FORCE
// var lengthOfLongestSubstring = function(s) {

//     let count = 0;

//     for (let i = 0; i < s.length; i++) {
//         let char = s.charAt(i);
//         let set = new Set([char]);

//         for (let j = i+1; j < s.length; j++) {
//             let char = s.charAt(j);
//             if (set.has(char)) {
//                 break;
//             } else {
//                 set.add(char);
//             }
//         }

//         if (set.size > count) {
//             count = set.size;
//         }

//     }

//     return count;
// };

//SLIDING WINDOW
var lengthOfLongestSubstring = function(s) {

    let count = 0;
    let i = 0;
    let j = 0;
    let n = s.length;
    let set = new Set();

    while (i < n && j < n) {
        let char = s.charAt(j);
        if(!set.has(char)) {
            set.add(char);
            j++;
            count = Math.max(count, j - i)
        } else {
            set.delete(s.charAt(i));
            i++;
        }
    }

    return count;
};

答案 13 :(得分:0)

C#定义最长子串长度不重复字符的解决方案:

public int LengthOfLongestSubstring(string s) {
        if (string.IsNullOrEmpty(s))
                return 0;
        if (s.Length==1)
                return 1;
        var l = 0;
            for (int i = 0; i < s.Length - 1; i++)
            {
                var tmp = "" + s[i];
                for (int j = i + 1; j < s.Length; j++)
                    if (tmp.Contains(s[j].ToString())) break;
                    else tmp += s[j];
                if (l < tmp.Length)
                    l = tmp.Length;
            }
            return l;
    }

答案 14 :(得分:0)

简单的python代码:

value = 0 
substring = ""

for i in s:
  if i not in substring:
    substring += i
    value = max(value, len(substring))
  else:
    cut_index = substring.index(i)
    substring = substring[cut_index+1:] + i

return value

答案 15 :(得分:0)

我已经用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();
    }

或者可以使用以下链接作为参考。

Git URL

答案 16 :(得分:0)

JavaScript的简化解决方案。

function longestUniqueString(s) {    
      let i = 0;
      let j = 0;
      let max = 0;
      let set = {};
      let longestString = "";
        
      while(i < s.length - max){
        if(!set[s[j]]){
          set[s[j]] = s[j]; 
          j++;
          max = Math.max(max, j-i);
          if(max <= j-i) longestString = Object.keys(set).join(""); 
        }else{
          i++;
          j = i;
          set = {};
        }
      }
      
      return longestString;
}

// I/O for snippet
console.log(longestUniqueString("stackoverflow"));

答案 17 :(得分:0)

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);
}

这是最快的,它是线性时间和恒定的空间

答案 18 :(得分:0)

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;
}

答案 19 :(得分:0)

算法:
1)初始化一个空字典 dct 以检查字符串中是否已存在任何字符。
2) cnt -在不重复字符的情况下保留子字符串的计数。
3) l r 是初始化为字符串的第一个索引的两个指针。
4)遍历字符串的每个字符。
5)如果 dct 中不存在该字符,请添加该字符并增加 cnt
6)如果已经存在,则检查 cnt 是否大于 resStrLen
7)从 dct 并向左移动指针1并减少计数。
8)重复5,6,7直到 l r 大于或等于该指针的长度。输入字符串。
9)最后再检查一次,以处理诸如带有非重复字符的输入字符串之类的情况。

这是简单的python程序,用于查找最长的子字符串而不重复字符< / strong>


pLQ->tail



答案 20 :(得分:0)

我们可以使用这样的东西吗?

def longestpalindrome(str1):
    arr1=list(str1)
    s=set(arr1)
    arr2=list(s)
    return len(arr2)



str1='abadef'
a=longestpalindrome(str1)
print(a)

仅返回子字符串的长度

答案 21 :(得分:0)

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

答案 22 :(得分:0)

这个问题可以用O(n)时间复杂度来解决。 初始化三个变量

  1. 开始(索引指向非重复子字符串的开头,将其初始化为0)。
  2. 结束(索引指向非重复子字符串的结尾,将其初始化为0)
  3. Hasmap(对象包含字符的最后访问索引位置。例如:{&#39; a&#39;:0,&#39; b&#39;:1}表示字符串&#34; ab&#34; )
  4. 步骤: 迭代字符串并执行以下操作。

    1. 如果hashmap()中不存在当前字符,请将其添加为 hashmap,字符作为键,索引作为值。
    2. 如果hashmap中存在当前字符,则

      a)检查起始索引是否小于或等于散列图中针对该字符的值(前面访问过的同一个字符的最后一个索引),

      b)它少于将起始变量值指定为散列图&#39;值+ 1(先前访问过的同一字符的最后一个索引+ 1);

      c)通过将hashmap的当前字符值替换为当前的字符索引来更新hashmap。

      d)将end-start计算为最长的子字符串值,并更新它是否大于先前最长的非重复子字符串。

    3. 以下是此问题的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;
      };
      

答案 23 :(得分:0)

问题:找到最长的子字符串而不重复字符。 例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);

答案 24 :(得分:0)

以下是在JavaScript中解决此问题的两种方法。

暴力方法是循环遍历字符串两次,检查每个子字符串与其他每个子字符串,并找到子字符串唯一的最大长度。我们需要两个函数:一个用于检查子串是否唯一,另一个函数用于执行双循环。

// O(n) time
const allUnique = str => {
  const set = [...new Set(str)];
  return (set.length == str.length) ? true: false;
}

// O(n^3) time, O(k) size where k is the size of the set
const lengthOfLongestSubstring = str => {
  let result = 0,
      maxResult = 0;
  for (let i=0; i<str.length-1; i++) {
    for (let j=i+1; j<str.length; j++) {
      if (allUnique(str.substring(i, j))) {
        result = str.substring(i, j).length;
        if (result > maxResult) {
          maxResult = result;
        }
      }
    }
  return maxResult;
  }
}

由于我们执行双循环O(n^3),然后在O(n^2)之上为我们的唯一函数执行另一个循环,因此时间复杂度为O(n)。空间是我们集合的大小,可以推广到O(n)或更准确O(k),其中k是集合的大小。

贪婪方法只循环一次并跟踪我们去的最大唯一子字符串长度。我们可以使用数组或哈希映射,但我认为新的.includes()数组方法很酷,所以让我们使用它。

const lengthOfLongestSubstring = str => {
  let result = [],
      maxResult = 0;

  for (let i=0; i<str.length; i++) {
    if (!result.includes(str[i])) {
      result.push(str[i]);
    } else {
      maxResult = i;
    }
  }

  return maxResult;
}

时间复杂度为O(n),空间复杂度为O(1)

答案 25 :(得分:0)

我将我的解决方案修改为&#34;找到最长子串的长度而不重复字符&#34;。

        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);
}

答案 26 :(得分:0)

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));
    }
}

答案 27 :(得分:0)

这是我的javascript和cpp实现,其中包含很多详细信息:https://algorithm.pingzhang.io/String/longest_substring_without_repeating_characters.html

我们希望找到最长的子字符串而不重复字符。我想到的第一件事是我们需要一个哈希表来存储子字符串中的每个字符,以便当一个新字符进入时,我们可以很容易地知道这个字符是否已经存在于子字符串中。我将其称为valueIdxHash。然后,子字符串具有startIdxendIdx。所以我们需要一个变量来跟踪子字符串的起始索引,我把它称为startIdx。假设我们处于索引i并且我们已经有一个子串(startIdx, i - 1)。现在,我们要检查此子字符串是否可以继续增长。

如果valueIdxHash 包含 str[i],则表示它是重复的字符。但是我们仍然需要检查这个重复的字符是否在子串(startIdx, i - 1)中。因此,我们需要检索上次出现的str[i]索引,然后将此索引与startIdx进行比较。

  • 如果startIdx较大,则表示最后一个str[i] 。因此子串可以继续增长。
  • 如果startIdx较小,则表示最后一次出现str[i]在子字符串。因此,子串不能再增长。 startIdx将更新为valueIdxHash[str[i]] + 1,新的子字符串(valueIdxHash[str[i]] + 1, i)有可能继续增长。

如果valueIdxHash 不包含 str[i],则子字符串可以继续增长。

答案 28 :(得分:0)

这是我的解决方案。希望它有所帮助。

  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;
    }

答案 29 :(得分:0)

经过测试和工作。为了便于理解,我想有一个抽屉可以放置字母。

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;
}

答案 30 :(得分:0)

不完全优化,但在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,这就是为什么它没有得到很好的优化。

答案 31 :(得分:0)

简单易用

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();
    }

}

答案 32 :(得分:0)

我在python中发布O(n ^ 2)。我只是想知道Karoly Horvath提到的技术是否有与现有搜索/排序算法类似的步骤?

我的代码:

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()

答案 33 :(得分:0)

这是我的解决方案,它被leetcode接受。然而,在我看到统计数据之后,我看到全部解决方案的结果要快得多......意思是,我的解决方案对于他们所有的测试用例大约是600ms,并且大多数js解决方案都在200-300毫秒左右。可以告诉我为什么我的解决方案很慢?

&#13;
&#13;
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;
};
&#13;
&#13;
&#13;

答案 34 :(得分:0)

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();
    }
}

答案 35 :(得分:-1)

private static String LongestSubString(String word)
{
    char[] charArray = word.toCharArray();
    HashSet set = new HashSet();
    String longestOverAll = "";
    String longestTillNow = "";
    for (int i = 0; i < charArray.length; i++) {
        Character c = charArray[i];

        if (set.contains(c)) {
            longestTillNow = "";
            set.clear();
        }
        longestTillNow += c;
        set.add(c);
        if (longestTillNow.length() > longestOverAll.length())
        {
            longestOverAll = longestTillNow;

        }
    }

    return longestOverAll;
}

答案 36 :(得分:-1)

private static string LongestSubstring(string word)
        {
            var set = new HashSet<char>();
            string longestOverAll = "";
            string longestTillNow = "";

            foreach (char c in word)
            {
                if (!set.Contains(c))
                {
                    longestTillNow += c;
                    set.Add(c);
                }
                else
                {
                    longestTillNow = string.Empty;
                }

                if (longestTillNow.Length > longestOverAll.Length)
                {
                    longestOverAll = longestTillNow;
                }
            }

            return longestOverAll;
        }