📜  Java程序在不重复字符的情况下查找最长子串的长度

📅  最后修改于: 2022-05-13 01:57:06.659000             🧑  作者: Mango

Java程序在不重复字符的情况下查找最长子串的长度

给定一个字符串str ,找出不重复字符的最长子字符串的长度。

  • 对于“ABDEFGABEF”,最长的子串是“BDEFGA”和“DEFGAB”,长度为6。
  • 对于“BBBB”,最长的子串是“B”,长度为 1。
  • 对于“GEEKSFORGEEKS”,下图中显示了两个最长的子串,长度为 7

所需的时间复杂度为 O(n),其中 n 是字符串的长度。

方法1(简单:O(n 3 )) :我们可以一一考虑所有子字符串,并检查每个子字符串是否包含所有唯一字符。将有 n*(n+1)/2 个子串。一个子串是否包含所有唯一字符,可以通过从左到右扫描它并保持一个已访问字符的映射在线性时间内检查。该解决方案的时间复杂度为 O(n^3)。

Java
// Java program to find the length of the
// longest substring without repeating
// characters
import java.io.*;
import java.util.*;
  
class GFG{
  
// This function returns true if all characters in
// str[i..j] are distinct, otherwise returns false
public static Boolean areDistinct(String str, 
                                  int i, int j)
{
      
    // Note : Default values in visited are false
    boolean[] visited = new boolean[26];
  
    for(int k = i; k <= j; k++)
    {
        if (visited[str.charAt(k) - 'a'] == true)
            return false;
              
        visited[str.charAt(k) - 'a'] = true;
    }
    return true;
}
  
// Returns length of the longest substring
// with all distinct characters.
public static int longestUniqueSubsttr(String str)
{
    int n = str.length();
      
    // Result
    int res = 0; 
      
    for(int i = 0; i < n; i++)
        for(int j = i; j < n; j++)
            if (areDistinct(str, i, j))
                res = Math.max(res, j - i + 1);
                  
    return res;
}
  
// Driver code
public static void main(String[] args)
{
    String str = "geeksforgeeks";
    System.out.println("The input string is " + str);
  
    int len = longestUniqueSubsttr(str);
      
    System.out.println("The length of the longest " +
                       "non-repeating character " + 
                       "substring is " + len);
}
}
  
// This code is contributed by akhilsaini


Java
// Java program to find the length of the 
// longest substring without repeating
// characters
import java.io.*;
import java.util.*;
  
class GFG{
  
public static int longestUniqueSubsttr(String str)
{
    int n = str.length();
      
    // Result
    int res = 0;
      
    for(int i = 0; i < n; i++)
    {
          
        // Note : Default values in visited are false
        boolean[] visited = new boolean[256];
          
        for(int j = i; j < n; j++)
        {
              
            // If current character is visited
            // Break the loop
            if (visited[str.charAt(j)] == true)
                break;
  
            // Else update the result if
            // this window is larger, and mark
            // current character as visited.
            else
            {
                res = Math.max(res, j - i + 1);
                visited[str.charAt(j)] = true;
            }
        }
  
        // Remove the first character of previous
        // window
        visited[str.charAt(i)] = false;
    }
    return res;
}
  
// Driver code
public static void main(String[] args)
{
    String str = "geeksforgeeks";
    System.out.println("The input string is " + str);
  
    int len = longestUniqueSubsttr(str);
    System.out.println("The length of the longest " +
                       "non-repeating character " +
                       "substring is " + len);
}
}
  
// This code is contributed by akhilsaini


Java
import java.io.*;
  
class GFG {
    public static int longestUniqueSubsttr(String str)
    {
        String test = "";
  
        // Result
        int maxLength = -1;
  
        // Return zero if string is empty
        if (str.isEmpty()) {
            return 0;
        }
        // Return one if string length is one
        else if (str.length() == 1) {
            return 1;
        }
        for (char c : str.toCharArray()) {
            String current = String.valueOf(c);
  
            // If string already contains the character
            // Then substring after repeating character
            if (test.contains(current)) {
                test = test.substring(test.indexOf(current)
                                      + 1);
            }
            test = test + String.valueOf(c);
            maxLength = Math.max(test.length(), maxLength);
        }
  
        return maxLength;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        System.out.println("The input string is " + str);
  
        int len = longestUniqueSubsttr(str);
        System.out.println("The length of the longest "
                           + "non-repeating character "
                           + "substring is " + len);
    }
}
  
// This code is contributed by Alex Bennet


Java
// Java program to find the length of the longest substring
// without repeating characters
import java.util.*;
  
public class GFG {
  
    static final int NO_OF_CHARS = 256;
  
    static int longestUniqueSubsttr(String str)
    {
        int n = str.length();
  
        int res = 0; // result
  
        // last index of all characters is initialized
        // as -1
        int [] lastIndex = new int[NO_OF_CHARS];
        Arrays.fill(lastIndex, -1);
  
        // Initialize start of current window
        int i = 0;
  
        // Move end of current window
        for (int j = 0; j < n; j++) {
  
            // Find the last index of str[j]
            // Update i (starting index of current window)
            // as maximum of current value of i and last
            // index plus 1
            i = Math.max(i, lastIndex[str.charAt(j)] + 1);
  
            // Update result if we get a larger window
            res = Math.max(res, j - i + 1);
  
            // Update last index of j.
            lastIndex[str.charAt(j)] = j;
        }
        return res;
    }
  
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        System.out.println("The input string is " + str);
        int len = longestUniqueSubsttr(str);
        System.out.println("The length of "
                           + "the longest non repeating character is " + len);
    }
}
// This code is contributed by Sumit Ghosh


Java
import java.util.*;
class GFG {
  
  static int longestUniqueSubsttr(String s)
  {
  
    // Creating a set to store the last positions of occurrence
    HashMap seen = new HashMap<>();  
    int maximum_length = 0;
  
    // starting the initial point of window to index 0
    int start = 0;
  
    for(int end = 0; end < s.length(); end++)
    {
      // Checking if we have already seen the element or not
      if(seen.containsKey(s.charAt(end)))
      {
        // If we have seen the number, move the start pointer
        // to position after the last occurrence
        start = Math.max(start, seen.get(s.charAt(end)) + 1);
      }
  
      // Updating the last seen value of the character
      seen.put(s.charAt(end), end);
      maximum_length = Math.max(maximum_length, end-start + 1);
    }
    return maximum_length;
  }
  
  // Driver code
  public static void main(String []args)
  {
    String s = "geeksforgeeks";
    System.out.println("The input String is " + s);
    int length = longestUniqueSubsttr(s);
    System.out.println("The length of the longest non-repeating character substring is " + length);
  }
}
  
// This code is contributed by rutvik_56.


输出
The input string is geeksforgeeks
The length of the longest non-repeating character substring is 7

方法2(更好:O(n 2 ))这个想法是使用窗口滑动。每当我们看到重复时,我们都会删除前一次出现并滑动窗口。

Java

// Java program to find the length of the 
// longest substring without repeating
// characters
import java.io.*;
import java.util.*;
  
class GFG{
  
public static int longestUniqueSubsttr(String str)
{
    int n = str.length();
      
    // Result
    int res = 0;
      
    for(int i = 0; i < n; i++)
    {
          
        // Note : Default values in visited are false
        boolean[] visited = new boolean[256];
          
        for(int j = i; j < n; j++)
        {
              
            // If current character is visited
            // Break the loop
            if (visited[str.charAt(j)] == true)
                break;
  
            // Else update the result if
            // this window is larger, and mark
            // current character as visited.
            else
            {
                res = Math.max(res, j - i + 1);
                visited[str.charAt(j)] = true;
            }
        }
  
        // Remove the first character of previous
        // window
        visited[str.charAt(i)] = false;
    }
    return res;
}
  
// Driver code
public static void main(String[] args)
{
    String str = "geeksforgeeks";
    System.out.println("The input string is " + str);
  
    int len = longestUniqueSubsttr(str);
    System.out.println("The length of the longest " +
                       "non-repeating character " +
                       "substring is " + len);
}
}
  
// This code is contributed by akhilsaini
输出
The input string is geeksforgeeks
The length of the longest non-repeating character substring is 7

方法 3(线性时间) :使用此解决方案,可以使用窗口滑动技术在线性时间内解决问题。每当我们看到重复时,我们都会删除窗口,直到出现重复的字符串。

Java

import java.io.*;
  
class GFG {
    public static int longestUniqueSubsttr(String str)
    {
        String test = "";
  
        // Result
        int maxLength = -1;
  
        // Return zero if string is empty
        if (str.isEmpty()) {
            return 0;
        }
        // Return one if string length is one
        else if (str.length() == 1) {
            return 1;
        }
        for (char c : str.toCharArray()) {
            String current = String.valueOf(c);
  
            // If string already contains the character
            // Then substring after repeating character
            if (test.contains(current)) {
                test = test.substring(test.indexOf(current)
                                      + 1);
            }
            test = test + String.valueOf(c);
            maxLength = Math.max(test.length(), maxLength);
        }
  
        return maxLength;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        System.out.println("The input string is " + str);
  
        int len = longestUniqueSubsttr(str);
        System.out.println("The length of the longest "
                           + "non-repeating character "
                           + "substring is " + len);
    }
}
  
// This code is contributed by Alex Bennet
输出
The input string is geeksforgeeks
The length of the longest non-repeating character substring is 7

方法4(线性时间) :现在让我们谈谈线性时间解决方案。此解决方案使用额外空间来存储已访问字符的最后索引。这个想法是从左到右扫描字符串,跟踪迄今为止在res中看到的最大长度非重复字符子字符串。当我们遍历字符串时,要知道当前窗口的长度,我们需要两个索引。
1)结束索引( j ):我们将当前索引视为结束索引。
2)起始索引( i ):如果当前字符不存在于前一个窗口中,则与前一个窗口相同。为了检查当前字符是否出现在前一个窗口中,我们将每个字符的最后一个索引存储在数组lasIndex[]中。如果 lastIndex[str[j]] + 1 大于先前的开始,那么我们更新了开始索引 i。否则我们保持相同的 i。

以下是上述方法的实现:

Java

// Java program to find the length of the longest substring
// without repeating characters
import java.util.*;
  
public class GFG {
  
    static final int NO_OF_CHARS = 256;
  
    static int longestUniqueSubsttr(String str)
    {
        int n = str.length();
  
        int res = 0; // result
  
        // last index of all characters is initialized
        // as -1
        int [] lastIndex = new int[NO_OF_CHARS];
        Arrays.fill(lastIndex, -1);
  
        // Initialize start of current window
        int i = 0;
  
        // Move end of current window
        for (int j = 0; j < n; j++) {
  
            // Find the last index of str[j]
            // Update i (starting index of current window)
            // as maximum of current value of i and last
            // index plus 1
            i = Math.max(i, lastIndex[str.charAt(j)] + 1);
  
            // Update result if we get a larger window
            res = Math.max(res, j - i + 1);
  
            // Update last index of j.
            lastIndex[str.charAt(j)] = j;
        }
        return res;
    }
  
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        System.out.println("The input string is " + str);
        int len = longestUniqueSubsttr(str);
        System.out.println("The length of "
                           + "the longest non repeating character is " + len);
    }
}
// This code is contributed by Sumit Ghosh
输出
The input string is geeksforgeeks
The length of the longest non-repeating character substring is 7

时间复杂度: O(n + d),其中 n 是输入字符串的长度,d 是输入字符串字母表中的字符数。例如,如果字符串由小写英文字符组成,则 d 的值为 26。
辅助空间: O(d)

替代实施:

Java

import java.util.*;
class GFG {
  
  static int longestUniqueSubsttr(String s)
  {
  
    // Creating a set to store the last positions of occurrence
    HashMap seen = new HashMap<>();  
    int maximum_length = 0;
  
    // starting the initial point of window to index 0
    int start = 0;
  
    for(int end = 0; end < s.length(); end++)
    {
      // Checking if we have already seen the element or not
      if(seen.containsKey(s.charAt(end)))
      {
        // If we have seen the number, move the start pointer
        // to position after the last occurrence
        start = Math.max(start, seen.get(s.charAt(end)) + 1);
      }
  
      // Updating the last seen value of the character
      seen.put(s.charAt(end), end);
      maximum_length = Math.max(maximum_length, end-start + 1);
    }
    return maximum_length;
  }
  
  // Driver code
  public static void main(String []args)
  {
    String s = "geeksforgeeks";
    System.out.println("The input String is " + s);
    int length = longestUniqueSubsttr(s);
    System.out.println("The length of the longest non-repeating character substring is " + length);
  }
}
  
// This code is contributed by rutvik_56.
输出
The input String is geeksforgeeks
The length of the longest non-repeating character substring is 7

作为练习,尝试上述问题的修改版本,您还需要打印最大长度 NRCS(上述程序只打印它的长度)。

有关详细信息,请参阅有关最长子串长度的完整文章,而不重复字符!