Posted on

Description

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

Submission

I used an array bucket to mark all the possible characters in ASCII table. This method is generally called Sliding Window.

There are several special cases as the following:

"": 0
"    ": 1 
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int beg = 0, end = 0;
        int longest_beg = 0, longest_end = 0;
        int [] bucket = new int[256];
        int longest_len = 1;
        
        if(s.length() == 0) {
            return 0;
        }
        
        for(; end < s.length(); end++) {
            bucket[s.charAt(end)]++;
            
            if(bucket[s.charAt(end)] == 2) {
                int curr_len = end - beg;
                if(curr_len > longest_len) {
                    longest_len = curr_len;
                }
                // remove the ones at the front
                while(bucket[s.charAt(end)] == 2) {
                    bucket[s.charAt(beg)]--;
                    beg++;
                } 
            } else {
                int curr_len = end - beg + 1;
                if(curr_len > longest_len) longest_len = curr_len;
            }
        }
        
        return longest_len;
    }
}

Solutions

Approach 1: Brute Force

This is a naive solution that for all the substrings of the string, check if there’s a repeated character. If there is, it should be discarded. It’s O(N^3).

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j <= n; j++)
                if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
        return ans;
    }

    public boolean allUnique(String s, int start, int end) {
        Set<Character> set = new HashSet<>();
        for (int i = start; i < end; i++) {
            Character ch = s.charAt(i);
            if (set.contains(ch)) return false;
            set.add(ch);
        }
        return true;
    }
}

Approach 2: Sliding Window

This approach applies sliding window using HashSet instead of an array.

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            }
            else {
                set.remove(s.charAt(i++));
            }
        }
        return ans;
    }
}

Approach 3: Sliding Window Optimized

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>(); // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return ans;
    }
}

Submission 210731

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        map<char, int> cnt;
        int ret = 0;
        for(int i = 0, j = 0; i < s.length() && j < s.length(); ++j) {
            if(++cnt[s[j]] == 2) {
                while(s[i] != s[j]) {
                    --cnt[s[i]];
                    ++i;
                }
                --cnt[s[i]];
                ++i;
            }
            ret = max(ret, j - i + 1);
        }
        return ret;
    }
};

Leave a Reply

Your email address will not be published. Required fields are marked *