leetcode解题方案--003--LongestSubstringWithoutRepeatingCharacters

题目

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.

解析

这道题和昨天做的滴滴笔试题还有点像,昨天的题目是:
给出n个数字,问有多少不重叠的非空区间,使得每个区间内的数字的xor等于0

异或为0的解法是动态规划,从头到尾遍历数组,为数组的每个位置构造一个list,存放当前xor不为0的区间的xor值,每次加入新的值,并将list里的每个数与当前数xor,若为0,则确定这是一个非空区间。需要注意的是,要选择好合适的数据结构,不要选择不安全的数据结构。

至于这道题,首先放出一个一般的解法,动态规划。

  • 动态规划用hashmap存遍历过的值,其中字符为键,数组下标为值
  • 如果当前字符不在map里,dp加1,代表当前区间长度
  • 如果当前字符在map里,取出上一次出现的位置,map清空,放入上一次出现的位置之后到当前位置所有的字符(典型case:dedgh ->4)
  • 求dp数组最大值
 public static int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() <=0) {
            return 0;
        }
        Map set = new HashMap<Integer, Integer>();
        char[] aa = s.toCharArray();
        int n = aa.length;
        int [] dp = new int[n];
        dp[0] = 1;
        set.put((int)aa[0], 0);
        for (int i = 1; i<n;i++) {
            if (set.containsKey((int)aa[i])) {
                int last = (int)set.get((int)aa[i]);
                set.clear();
                for (int j = last+1; j<=i; j++) {
                    set.put((int)aa[j], j);
                }
                dp[i] = i-last;
            } else {
                dp[i] = dp[i-1]+1;
                set.put((int)aa[i], i);
            }
        }
        int max=0;
        for (int i = 0; i<n;i++) {
            if (max<dp[i]) {
                max= dp[i];
            }
        }
        return max;
    }

这种解法运行时间很长,超越了4%的人
下面列出另外一种方法:

  • seen数组代表最近出现的位置+1
  • 如果出现了重复的,重置head为当前不重复字符串的位置
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s.length() < 2)
            return s.length();

        int longest = 0;
        int[] seen = new int[128];
        for (int i = 0, head = 0, length = s.length(); i < length; i++) {
            int c = s.charAt(i);
            if (seen[c]-1 >= head) {
                head = seen[c];
            } else {
                longest = Math.max(longest, i-head+1);
            }
            seen[c] = i+1;
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值