[LC]3. Longest Substring Without Repeating Characters

一、问题描述

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

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", 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.

二、我的解法

时间O(n^2)的解法,i有n个开始点,j有n个可能的结束点。每次只判断s[j]是否在当前的substring里。 (是n2还是n3?)

用hashSet帮助判断当前要加入的char是否已经存在在substring里。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        char[] char_arr = s.toCharArray();
        
        int max_len = 0;
        int cur_len;
        Set<Character> appeared = new HashSet<Character>();
        for(int i = 0; i < char_arr.length; i ++){
            int j = i;
            appeared.clear();
            cur_len = 0;
            while(j < char_arr.length && appeared.add(char_arr[j])){
                cur_len ++;
                j ++;
            }
            if(cur_len > max_len){
                max_len = cur_len;
            }
        }
        return max_len;
    }
}

三、淫奇技巧

https://leetcode.com/articles/longest-substring-without-repeating-characters/

1. O(2n)解法

滑动窗口。从左往右扫描,当遇到重复字母时,以上一个重复字母的index +1,作为新的搜索起始位置。因为设s[j]是substring[i, j)的重复元素。如果再从包含s[j]的字串i+1重新搜索已经没有必要了,因为该字串结果必定小于[i, j)。所以直接从重复字母的index +1,作为新的搜索起始位置。

当要加入的s[j]重复了,就从hashset里依次删除元素,直到把重复的那个元素删除为止,再把s[j]加入。

  • Time complexity : O(2n) = O(n)O(2n)=O(n). 最坏情况是每个元素被i和j各遍历一遍。

  • Space complexity : O(min(m, n))O(min(m,n)). 和我的解法一样。m是input string里不同char的数量,n是string长度。

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


2. O(n解法)

思路和上面解法一样,但是怎样从index+1开始搜索更胜一筹。存储用了hashmap,有char到index的映射信息。

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


四、反思&收获

1. hashset是好东西

2. 多存有用的信息可以减少复杂度;

3. 算复杂度要继续加强

4. 搜索字符串策略的优化要加强~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值