leetcode解题方案--003--LongestSubstringWithoutRepeatingCharacters

来源:互联网 发布:竞争对手数据分类 编辑:程序博客网 时间:2024/05/17 21:42

题目

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;     }}
原创粉丝点击