Java 没有重复字符的最长公共子字符串的长度

Java 没有重复字符的最长公共子字符串的长度,java,longest-substring,Java,Longest Substring,给定“abcabcbb”,答案是“abc”,长度为3。 给定“bbbbb”,答案是“b”,长度为1。 给定“pwwkew”,答案是“wke”,长度为3。请注意,答案必须是子字符串,“pwke”是子序列,而不是子字符串。 我提出了一个可行的解决方案,但在几个测试用例中失败了。然后我找到了一个更好的解决方案,我重写了它,试图理解它。下面的解决方案可以完美地工作,但是经过大约2个小时的斗争,我仍然无法理解为什么这一行代码可以工作 import java.util.*; import java.math

给定“abcabcbb”,答案是“abc”,长度为3。

给定“bbbbb”,答案是“b”,长度为1。

给定“pwwkew”,答案是“wke”,长度为3。请注意,答案必须是子字符串,“pwke”是子序列,而不是子字符串。

我提出了一个可行的解决方案,但在几个测试用例中失败了。然后我找到了一个更好的解决方案,我重写了它,试图理解它。下面的解决方案可以完美地工作,但是经过大约2个小时的斗争,我仍然无法理解为什么这一行代码可以工作

import java.util.*;
import java.math.*;

public class Solution {

  public int lengthOfLongestSubstring(String str) {

  if(str.length() == 0)
    return 0;

  HashMap<Character,Integer> map = new HashMap<>();
  int startingIndexOfLongestSubstring = 0;
  int max = 0;

  for(int i = 0; i < str.length(); i++){
      char currentChar = str.charAt(i); 
      if(map.containsKey(currentChar))
         startingIndexOfLongestSubstring = Math.max(startingIndexOfLongestSubstring, map.get(currentChar) + 1);

      map.put(currentChar, i);
      max = Math.max(max, i - startingIndexOfLongestSubstring + 1);

      }//End of loop

    return max;

   }
}
import java.util.*;
导入java.math.*;
公共类解决方案{
public int lengthOfLongestSubstring(字符串str){
如果(str.length()==0)
返回0;
HashMap=newHashMap();
int startingIndexOfLongestSubstring=0;
int max=0;
对于(int i=0;i
所讨论的行是max=Math.max(max,i-startingIndexOfLongestSubstring+1)

max = Math.max(max, i - startingIndexOfLongestSubstring + 1); 我不明白为什么会这样。我们取上一个最大值之间的最大值,以及当前索引和当前最长子字符串的起始索引之间的差值,然后加1。我知道代码得到了我们当前索引和startingIndexOfSubstring之间的差异,但我无法概念化为什么它能给我们预期的结果;有人能给我解释一下这一步吗,特别是为什么它会起作用?

因为

i - startingIndexOfLongestSubstring + 1
i
startingIndexOfLongestSubstring
索引之间的字符数。例如,位置2和3之间有多少个字符<代码>3-2=1
但我们有两个字符:位置2和位置3

我已经描述了代码中的每个操作:

public class Solution {

    public int lengthOfLongestSubstring(String str) {

        if(str.length() == 0)
            return 0;

        HashMap<Character,Integer> map = new HashMap<>();
        int startingIndexOfLongestSubstring = 0;
        int max = 0;

        // loop over all characters in the string
        for(int i = 0; i < str.length(); i++){
            // get character at position i
            char currentChar = str.charAt(i);
            // if we already met this character
            if(map.containsKey(currentChar))
                // then get maximum of previous 'startingIndexOfLongestSubstring' and 
                // map.get(currentChar) + 1 (it is last occurrence of the current character in our word before plus 1)
                // "plus 1" - it is because we should start count from the next character because our current character 
                // is the same
                startingIndexOfLongestSubstring = Math.max(startingIndexOfLongestSubstring, map.get(currentChar) + 1);

            // save position of the current character in the map. If map already has some value for current character 
            // then it will override (we don't want to know previous positions of the character)
            map.put(currentChar, i);
            // get maximum between 'max' (candidate for return value) and such value for current character
            max = Math.max(max, i - startingIndexOfLongestSubstring + 1);

        }//End of loop

        return max;

    }
}
公共类解决方案{
public int lengthOfLongestSubstring(字符串str){
如果(str.length()==0)
返回0;
HashMap=newHashMap();
int startingIndexOfLongestSubstring=0;
int max=0;
//循环字符串中的所有字符
对于(int i=0;i
i - startingIndexOfLongestSubstring + 1
i
startingIndexOfLongestSubstring
索引之间的字符数。例如,位置2和3之间有多少个字符<代码>3-2=1
但我们有两个字符:位置2和位置3

我已经描述了代码中的每个操作:

public class Solution {

    public int lengthOfLongestSubstring(String str) {

        if(str.length() == 0)
            return 0;

        HashMap<Character,Integer> map = new HashMap<>();
        int startingIndexOfLongestSubstring = 0;
        int max = 0;

        // loop over all characters in the string
        for(int i = 0; i < str.length(); i++){
            // get character at position i
            char currentChar = str.charAt(i);
            // if we already met this character
            if(map.containsKey(currentChar))
                // then get maximum of previous 'startingIndexOfLongestSubstring' and 
                // map.get(currentChar) + 1 (it is last occurrence of the current character in our word before plus 1)
                // "plus 1" - it is because we should start count from the next character because our current character 
                // is the same
                startingIndexOfLongestSubstring = Math.max(startingIndexOfLongestSubstring, map.get(currentChar) + 1);

            // save position of the current character in the map. If map already has some value for current character 
            // then it will override (we don't want to know previous positions of the character)
            map.put(currentChar, i);
            // get maximum between 'max' (candidate for return value) and such value for current character
            max = Math.max(max, i - startingIndexOfLongestSubstring + 1);

        }//End of loop

        return max;

    }
}
公共类解决方案{
public int lengthOfLongestSubstring(字符串str){
如果(str.length()==0)
返回0;
HashMap=newHashMap();
int startingIndexOfLongestSubstring=0;
int max=0;
//循环字符串中的所有字符
对于(int i=0;i
我通常不善于解释,让我举个例子来说明一下

字符串是“wcabcdeghi”。

先把代码忘了,然后假设我们正试图想出一个逻辑。

  • 我们从w开始,一直走到c->a->b->c.
    我们需要在这一点上停止,因为“c”在重复。因此,如果一个字符重复,我们需要一个映射来存储。(在代码中:
    map.put(currentChar,i);