[英]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.