【leetcode】LongestSubstringWithoutRepeatingCharacters

  • 题目

    求最长的无重复字符的子串

  • 思路1
    • 最长无重复子串肯定包含在两个重复字符之间,用len保存当前最长的子串。如果某两个重复字符之间的子串长于len,则给len赋值这个新的长度。
    • 定义一个标志位数组,大小为128,表示从空格到abcd……xyzABC……XYZ,都用ASCII码表示,某一个字符出现,就在对应的位置1,比如出现a,就在数组的第65位置1.ASCII码为0的为'\0',用a-'\0'得到aASCII码值.
  • 思路2

    BF方法的时间复杂度是O(n^3),对每个substring都看看是不是有重复的字符,找出其中最长的。优化的方法是通过动态规划。

  • 思路3
    • 线性的方法,常用方法,基本思路是维护一个窗口,每次关注窗口中的字符串,每次判断中,左窗口和右窗口选择其一向前移动。
    • 正常情况下移动右窗口,如果没有出现重复则继续移动有窗口,如果发现重复字符,则说明当前窗口中的串已经不满足要求,继续移动右窗口不可能得到更好的结果,此时移动左窗口,直到不再有重复字符为止。
  • 代码

    package leetcode.longestsubstringwithoutRepeatingCharacters;

       

    import java.util.ArrayList;

    import java.util.HashMap;

    import java.util.HashSet;

    import java.util.Iterator;

       

    public class LongestSubstringWithoutRepeatingCharacters {

       

    static int[] last = new int[128];//last数组用于保存新出现的字符的下标

       

    public static int lengthOfLongestSubstring(String s) {

    int start = 0;

    int len = 0;

    char[] w = new char[s.length()];//将字符串转换为字符数组

    w = s.toCharArray();

    System.out.println(w[1]-' ');

    for (int i = 0; i < 128; i++)

    last[i] = -1;// last数组用于保存新出现的字符的下标,一开始全部初始化为-1

    for (int i = 0; i < s.length(); ++i) {

    if (last[w[i] - ' '] >= start) { // 当前这个字符出现过

    if (i - start > len)

    len = i - start;

    start = last[w[i] - ' '] + 1; // 从这个字符首次出现的位置+1,重新扫描,相当于把前面抛开前面的字符串不谈

    }

    last[w[i] - ' '] = i;// 更新当前字符的下标

    }

    if (len > s.length() - start)// 针对没有重复字符的字符串

    return len;

    else

    return s.length() - start;

    }

       

    public static void main(String args[]) {

    String s = "aabcbab";

    int l = lengthOfLongestSubstring(s);

    System.out.println(l);

    }

    }

       

posted @ 2015-03-25 19:43  keedor  阅读(168)  评论(0编辑  收藏  举报