[question brushing plan] the longest substring without repeated characters

Posted by edwardsbc on Fri, 03 Dec 2021 08:00:05 +0100

Due to the epidemic situation, starting from today, telecommuting from home seems unnecessary, but it is still inconvenient

  • Eating is a big problem. In the past, I ate in the company canteen and went to eat at the appointed time. Now I either make it myself or take out is very troublesome
  • Working hours become longer. I catch the bus at 10:00 in the company. I don't have the concept of time at home. At the same time, I feel that there are more tasks. Everyone is working overtime, and the internal volume is more serious

Alas, it's too difficult to take time to brush the questions

If you brush it, you won't remember it. If you remember the new question type, you still won't. OK, do you want to brush it?

1 today's topic

Given a string s, please find the length of the longest substring that does not contain duplicate characters.

Example 1:

Input: s = "abcabcbb" output: 3 explanation: because the longest substring without repeated characters is "abc", its length is 3. Example 2:

Input: s = "bbbbb" output: 1 explanation: because the longest substring without repeated characters is "b", its length is 1. Example 3:

Input: s = "pwwkew" output: 3 explanation: because the longest substring without repeated characters is "wke", its length is 3. Please note that your answer must be the length of the substring, "pwke" is a substring, not a substring. Example 4:

Input: s = "" output: 0

thinking

The difficulty of this problem is medium. I think it's very difficult. If I haven't touched it, it's estimated that it's difficult to do it with low algorithm complexity,

The sliding window algorithm is mainly studied

It sounds like "sliding window" is awesome. In fact, it is similar to double pointers,

Within the two pointers are the eligible elements

If an element that does not meet the criteria is encountered, the two pointers move to the right to eliminate the leftmost element

For example, abc is a window. When a is encountered again, it becomes bca in the window

The code is implemented as follows, and the algorithm complexity is O(n2)

public static int lengthOfLongestSubstring2(String s) {
    if (s.length() == 0) {
        return 0;
    }
    int result = 0;
    int left = 0;
    int right = 0;
    int length = 0;
    char[] data = s.toCharArray();
    List<Character> subString = new ArrayList<>();
    while (right < data.length) {
        int index = subString.indexOf(data[right]);
        while (index >= 0) {
            result = Math.max(result, right - left);
            subString.remove(0);
            length = subString.size();
            left++;
            index = subString.indexOf(data[right]);
        }
        length++;
        subString.add(data[right]);
        right++;
    }
    return Math.max(result, length);
}

Optimization 1

public int lengthOfLongestSubstring3(String s) {
    if (s.length() == 0) {
        return 0;
    }
    Set<Character> subString = new HashSet<>();
    int result = 0;
    int left = 0, right = 0;
    while (right < s.length()) {
        char c = s.charAt(right);
        while (subString.contains(c)) {
            subString.remove(s.charAt(left));
            left++;
        }
        subString.add(c);
        right++;
        result = Math.max(result, subString.size());
    }
    return result;
}

Optimization 2

In the scheme implemented above, when judging whether the current character is outdated, it is traversed again from the previously traversed data

This efficiency is certainly not high, so consider optimizing through the hash table

public static int lengthOfLongestSubstring(String s) {
    int result = 0;
    if (s.length() == 0) {
        return result;
    }
    // Save the position of the element in the map if the next character appears in the map
    // Prove that the window needs to be moved to the left, and the left pointer of the window is the next repeated element in the map
    Map<Character, Integer> char2index = new HashMap<>();
    //The left and right pointers of start and end form a sliding window
    for (int start = 0, end = 0; end < s.length(); end++) {
        char element = s.charAt(end);
        if (char2index.containsKey(element)) {
            //char2index.get(), which is the key point
            start = Math.max(char2index.get(element) + 1, start);
        }
        result = Math.max(result, end - start + 1);
        char2index.put(element, end);
    }
    return result;
}

2 Summary

The related topics of sliding window are still very regular. Try to take some time tomorrow to summarize and summarize the topics of sliding window and sort out the related topics.