简体   繁体   English

Java 滑动窗口问题:给定一个字符串,找出最长的子字符串的长度,它包含所有不同的字符。 比较解决方案

[英]Java Sliding Window Problem: Given a string, find the length of the longest substring, which has all distinct characters. Comparing Solutions

I am taking a course to prepare for coding interviews and how it works is I try a problem then the solution is presented.我正在上一门课程来准备编码面试,它的工作原理是我尝试一个问题然后提出解决方案。

Question: Given a string, find the length of the longest substring, which has all distinct characters.问题:给定一个字符串,找出所有不同字符的最长子字符串的长度。

Example: Input: String="aabccbb" Output: 3 Explanation: The longest substring with distinct characters is "abc".示例:输入:String="aabccbb" 输出:3 解释:具有不同字符的最长子字符串是“abc”。

I was wondering if there is any reason to use a HashMap and not an ArrayList on this problem?我想知道在这个问题上是否有任何理由使用 HashMap 而不是 ArrayList? I will show both solutions and I was wondering if mine is wrong for any reason or if it is inefficient?我将展示这两种解决方案,我想知道我的解决方案是否因任何原因出错或效率低下?

My solution works and the output matches (3,2,3).我的解决方案有效并且输出匹配(3,2,3)。 That's why I am wondering if I am doing anything wrong because their solution seems so much more complex than needed?这就是为什么我想知道我是否做错了什么,因为他们的解决方案似乎比需要的复杂得多?

My Solution:我的解决方案:

import java.util.*;
class NoRepeatSubstring {
  public static int findLength(String str) {
    // TODO: Write your code here
    List<Character> charList = new ArrayList<Character>();
    int maxLength = 0;

    for(int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
      
      while(charList.contains(str.charAt(windowEnd))) {
        charList.remove(0);
      }
      
      charList.add(str.charAt(windowEnd));
      
      if(charList.size() > maxLength) {
        maxLength = charList.size();
      }
    }
    return maxLength;
  }

  public static void main(String[] args) {
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("aabccbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abbbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abccde"));
  }

}



Their Solution:他们的解决方案:

import java.util.*;

class NoRepeatSubstring {
  public static int findLength(String str) {
    int windowStart = 0, maxLength = 0;
    Map<Character, Integer> charIndexMap = new HashMap<>();
    // try to extend the range [windowStart, windowEnd]
    for (int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
      char rightChar = str.charAt(windowEnd);
      // if the map already contains the 'rightChar', shrink the window from the beginning so that
      // we have only one occurrence of 'rightChar'
      if (charIndexMap.containsKey(rightChar)) {
        // this is tricky; in the current window, we will not have any 'rightChar' after its previous index
        // and if 'windowStart' is already ahead of the last index of 'rightChar', we'll keep 'windowStart'
        windowStart = Math.max(windowStart, charIndexMap.get(rightChar) + 1);
      }
      charIndexMap.put(rightChar, windowEnd); // insert the 'rightChar' into the map
      maxLength = Math.max(maxLength, windowEnd - windowStart + 1); // remember the maximum length so far
    }

    return maxLength;
  }

  public static void main(String[] args) {
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("aabccbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abbbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abccde"));
  }
}


charList.contains(str.charAt(windowEnd)) is O(n) while charIndexMap.containsKey(rightChar) is ( usually ) O(1). charList.contains(str.charAt(windowEnd))是 O(n) 而charIndexMap.containsKey(rightChar)是( 通常) O(1)。

charList.contains goes through the whole list to check if the character is in the list. charList.contains遍历整个列表以检查字符是否在列表中。 charIndexMap.containsKey hashes the character/key, which is constant in time. charIndexMap.containsKey对字符/键进行哈希处理,该字符/键在时间上是恒定的。

(It would be even faster to use an array of booleans with a fixed size of 2^8 (=the number of possible characters) and use the character as index into the array. That would be guaranteed to be O(1) and would also be faster with small strings since no time is wasted on computing hashes.) (使用固定大小为 2^8(=可能的字符数)的布尔数组并将字符用作数组的索引会更快。这将保证为 O(1) 并且使用小字符串也更快,因为没有时间浪费在计算哈希上。)

ArrayList's contains method is O(N) but of HashMap is mostly O(1). ArrayList 的 contains 方法是 O(N),但 HashMap 的主要是 O(1)。 Infact you dont even need to use a HashMap here , even HashSet will do.事实上,你甚至不需要在这里使用 HashMap,甚至 HashSet 都可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取任何给定输入字符串中带有不同字符的最长子字符串的长度 - Get the length of longest substring with distinct characters in any given input string 最小长度子字符串具有原始字符串的所有不同字符的滑动窗口解决方案 - Sliding window solution for min length substring with all distinct characters of the original string 如何打印“ ALL”具有存储在array(JAVA)中的最长length()的最长字符串的问题 - Problem with how to print “ALL” the longest string which have SAME longest length() that stored in array(JAVA) 查找没有连续重复字符的最长子字符串的长度 - Find the length of the longest substring with no consecutive repeating characters 求不重复字符的最长子串的长度 - Find the length of the longest substring without repeating characters 如何找到给定字符串的最长重复子字符串 - How to find the longest repeated substring of given string 查找由其他字符串的字符组成的最长子字符串 - Find longest substring formed with characters of other string 查找最长的 Substring 没有重复字符 - Java - Find the Longest Substring without Repeating Characters - Java 代码来查找最长的唯一K字符子字符串,不适用于所有输入 - code to find longest substring with unique K characters not working for all inputs 给定一个字符串,找到具有相同元音和辅音数量的最长子字符串? - Given a string, find the longest substring with the same number of vowels and consonants?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM