3.无重复字符的最长字串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
1.自己的解法
class Solution {
   public int lengthOfLongestSubstring(String s) {
            HashMap map=new HashMap();
            int max=0,start=0,len=0;
            for(int i=0;i<s.length();i++) {
                if(map.containsKey(s.charAt(i))) {
                    start=Math.max((int) map.get(s.charAt(i))+1, start);
                }
                map.put(s.charAt(i), i);
                len=i-start+1;
                if(len>max) {
                    max=len;
                }
            }
            return max; 
        }
}

记录每一个字符下次出现的位置,根据位置的更新最长长度会改变,start开始端的更新1.不能比当前的小2.再原始位置后移一个;一开始想要设置一个end位记录最长字符串的末尾,但是发现应该就是i对应的,所以没有设置,而之前的长度记录在max中

2.官方题解:
1.暴力解法:

对每个子字符判断是否含有不同的字符:

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;
    }
}

2.滑动窗口:

对[i,j)的字符都不在set中,判断[i,j+1)在不在即右移窗口,当j在set中时,把i对应的字符从set中去除,i++对每个i重复操作:

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;
    }
}

3.优化的滑动窗口(同我的做法):

与(2)相同,只不过将i更新为j+1

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;
    }
}

4.ascii码解法:

用ascii码代替hashmap:

 public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        int[] index = new int[128]; // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
            i = Math.max(index[s.charAt(j)], i);
            ans = Math.max(ans, j - i + 1);
            index[s.charAt(j)] = j + 1;
        }
        return ans;
    }

------------------------------------------------------------------------------------------------

 
原文地址:https://www.cnblogs.com/code-fun/p/12489741.html