文章标题 leetcode刷题日记——最长子串

来源:互联网 发布:雨滴软件 编辑:程序博客网 时间:2024/06/05 16:58

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(n3),这个可以动手算一下

public class demo1 {public static void main(String[] args) {       Scanner Sc =new Scanner(System.in);       while(true){       String s=Sc.nextLine();       System.out.println(longSubString(s));       }}public static int lengthOfLongestSubstring(String s){      int n=s.length();      int max=1;      for(int i=0;i<n;i++){        for(int j=i+1;j<n;j++){       if(test(s,i,j))          max=Math.max(ans, j - i);           else           break;         }      }      return max;    }public static boolean test(String str,int start,int end){       Set<Character> set=new HashSet<Character>();            for(int i=start;i<=end;i++){         char c=str.charAt(i);            if(set.contains(c)==true)                return false;            set.add(c);        }          return true;   }}```算法二: 在算法一中为了检查子串中是否有重复的字符,做了大量重复的工作.对此可以做出改进。如果子串从i到j中,其i到j-1都已经检查过,则只需检查j在不在子串中。将i,j 这个窗口进行滑动。该算法j指针只往后移动,没有回溯。时间复杂度:O(2n)=O(n)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;    }}

算法三:二解法中依然要求遍历2n次,其实可以进一步优化使其遍历n步。我们可以不使用set集合去判断是否存在一个字符,我们可以定义一个哈希map,用字符作为它的key值,所在序列号作为value值。二中i 和j均从头遍历到尾2n次。假设从从i到j的串总j处字符与j1处字符重复,则此时可以让i从j1+1处开始遍历。

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))+1, i);            }            ans = Math.max(ans, j - i + 1);            map.put(s.charAt(j), j );        }        return ans;    }}算法四:The previous implements all have no assumption on the charset of the string s.If we know that the charset is rather small, we can replace the Map with an integer array as direct access table.Commonly used tables are:    int[26] for Letters 'a' - 'z' or 'A' - 'Z'    int[128] for ASCII    int[256] for Extended ASCIIpublic class Solution {    public int lengthOfLongestSubstring(String s) {        int n = s.length(), ans = 0;        int[] index = new int[128]; // current index of character        // try to extend the range [i, j]        for (int j = 0, i = 0; j < n; j++) {            i = Math.max(index[s.charAt(j)], i);            ans = Math.max(ans, j - i + 1);            index[s.charAt(j)] = j + 1;        }        return ans;    }}

一个字符串问题一般都可以考虑多种算法思路。

阅读全文
0 0
原创粉丝点击