leetcode 3. Longest Substring Without Repeating Characters

题目内容

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

Example:
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.

分析过程

  • 题目归类:
    array,遍历,dp
  • 题目分析:
    找到连续字串,输出最长的没有重复字母的连续字串。
    采用循环法一定可以做出来,但是时间复杂度太差,最差是O(n^2),因为每次子串增长1都需要遍历一次看看有没有重复的数据,可以用一个hashmap来记录子串的数据。其中key为 char,value 为 index。那么每次做的就是
    1. 定义 i,j 分别为字串的起始和终点,创建一个HashMap 保存所有在ij 中的数据。
      2.查询index = map.get(String.charAt(j))是否在ij之间,如果在,*(当i==j时不更新)将hashmap 更新,并把i = index+1;计算一个sum的值。
  • 边界分析:
    • 空值分析、
      如果string 为 null 则返回null
    • 循环边界分析
      j的值不大于string.size();
  • 方法分析:
    • 数据结构分析
      hashmap保存数据可以降低循环的次数。
    • 状态机
    • 状态转移方程
    • 最优解
  • 测试用例构建
    [],
    [a,a,a,a]
    [a]
    [abca]

代码实现

import java.util.*;
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length()==0)
            return 0;
        int sum = 1;
        HashMap<Character,Integer> map = new HashMap<>();
        int i = 0;
        for(int j = 0 ; j < s.length();j++){
            char ch = s.charAt(j);
            if(map.containsKey(ch)){
                int index = map.get(ch);
                if(sum < j-i)
                    sum = j-i;
                for(;i<=index;i++)
                    map.remove(s.charAt(i));
                i = index+1;
            }
             map.put(ch,j);
        }
        if(sum >= s.length()-i)
            return sum;
        else
            return s.length()-i;
    }
}

题目内容

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

Example:
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.

分析过程

  • 题目归类:
    array,遍历,dp
  • 题目分析:
    找到连续字串,输出最长的没有重复字母的连续字串。
    采用循环法一定可以做出来,但是时间复杂度太差,最差是O(n^2),因为每次子串增长1都需要遍历一次看看有没有重复的数据,可以用一个hashmap来记录子串的数据。其中key为 char,value 为 index。那么每次做的就是
    1. 定义 i,j 分别为字串的起始和终点,创建一个HashMap 保存所有在ij 中的数据。
      2.查询index = map.get(String.charAt(j))是否在ij之间,如果在,*(当i==j时不更新)将hashmap 更新,并把i = index+1;计算一个sum的值。
  • 边界分析:
    • 空值分析、
      如果string 为 null 则返回null
    • 循环边界分析
      j的值不大于string.size();
  • 方法分析:
    • 数据结构分析
      hashmap保存数据可以降低循环的次数。
    • 状态机
    • 状态转移方程
    • 最优解
  • 测试用例构建
    [],
    [a,a,a,a]
    [a]
    [abca]

代码实现

import java.util.*;
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length()==0)
            return 0;
        int sum = 1;
        HashMap<Character,Integer> map = new HashMap<>();
        int i = 0;
        for(int j = 0 ; j < s.length();j++){
            char ch = s.charAt(j);
            if(map.containsKey(ch)){
                int index = map.get(ch);
                if(sum < j-i)
                    sum = j-i;
                for(;i<=index;i++)
                    map.remove(s.charAt(i));
                i = index+1;
            }
             map.put(ch,j);
        }
        if(sum >= s.length()-i)
            return sum;
        else
            return s.length()-i;
    }
}

效率提高

一种更好的方法就是不用每次都清理hashmap,可以保持hashmap只不过判断时候 i = Math.max(i,map.get(s.charAt(j))+1);

拓展问题

Longest Substring with At Most Two Distinct Characters
Medium
Longest Substring with At Most K Distinct Characters
Hard
Subarrays with K Different Integers
Hard

posted @ 2020-02-07 12:28  clnsx  阅读(94)  评论(0编辑  收藏  举报