3. Longest Substring Without Repeating Characters(Medium)

题目描述

原题

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.

原题翻译

描述
给定一个字符串,找到最长的不重复子串的长度。

例1

输入: “abcabcbb”
输出: 3
解释: 最长的不重复子串为"abc",长度为3。

例2

输入: “bbbbb”
输出: 1
解释: 最长的不重复子串为"b",长度为3。

例3

输入: “pwwkew”
输出: 3
解释: 最长的不重复子串为"wke",长度为3。
注意,答案必须是子字符串,“pwke”是子数组而不是子字符串。

解法一

主要思想

遍历String对应的char[],将char和index放入Map,对Map中已有的char进行覆盖。

源码

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int len = s.length();
        if(len <= 1)
            return len;
        Map<Character, Integer> map = new HashMap<>();
        char[] chars = s.toCharArray();
        int temp = 0;
        int max = 0;
        for(int i = 0; i < len; i++) {
            if(!map.containsKey(chars[i])) {
                map.put(chars[i], i);
                temp++;
            } else {
                if(i - map.get(chars[i]) > temp) { // 当前字母不在temp里
                    temp++;
                } else {
                    max = Math.max(max, temp);
                    temp = i - map.get(chars[i]);
                }
                map.put(chars[i], i);
            }
        }
        max = Math.max(max, temp);
        return max;
    }
}

解法二

主要思想

利用StringBuilder的API。

源码

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        StringBuilder substring = new StringBuilder();
        int longestLength = 0;
        for(int i =0; i< s.length(); i++) {
            String currentLetter = Character.toString(s.charAt(i));
            if (substring.indexOf(currentLetter) != -1 ) { // StringBuilder中已存在该字符
                longestLength = Math.max(substring.length(), longestLength);
                int endIndexToDelete = substring.indexOf(currentLetter) +1;
                substring.delete(0, endIndexToDelete);
            }
            substring.append(currentLetter);
        }
        longestLength = Math.max(substring.length(), longestLength);
        return longestLength;
    }
}

解法三

第一名答案,难以想象它竟然是一位中国人给出的(代码里有中文注释)。作为一个中国人,给出一个String,他竟然能想到ascii码…

主要思想

一个boolean[128]表示128个ascii字符。

源码

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
	    return 0;
        }
        boolean[] exist = new boolean[128]; // 表示acii码的128个字符
        int max = 0, start = 0; // start用来记录无重复子串的开始位置
        for (int i = 0, len = s.length(); i < len; i++) {
            char c = s.charAt(i);
            if (exist[c]) { 
                max = Math.max(max, i - start);
                // 每次当数组中出现一个重复字符 c 的时候,将之前一个重复的 c 之前的元素设为未出现(exist[i]=false)
                for (int j = start; j < i; j++) {
                    if (s.charAt(j) == c) {
                        start = j + 1;
		        break;
                    }
                    exist[s.charAt(j)] = false;
                }
            } else {
                exist[c] = true;
            }
        }
        return Math.max(s.length() - start, max);
}

猜你喜欢

转载自blog.csdn.net/gaoxuekun/article/details/86665028