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".
I was wondering if there is any reason to use a HashMap and not an ArrayList on this problem? 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). 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"));
}
}