1. 程式人生 > >Leetcode/【1】/longest substring without repeating characters

Leetcode/【1】/longest substring without repeating characters

寫在最前面:機器學習也要搞,leetcode也要刷,為了方便大家除錯,給的程式碼都是添加了測試程式碼的,直接執行即可

題目如下:

Leetcode/1/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.

給定一個字串s,找出不含有重複字元的最長子串的長度

首先是暴力法:基本思路是通過ifallUnique函式查詢該字串是否包含重複字元,是的話返回false,否則的話將新的字元加進去,因為給的是一個字串,將字串挨個轉成Character型別,然後兩層迴圈遍歷,通過ans記錄已經存在的最長字串,max函式比較下一組不包含重複字元的字串的長度

package Arithmetic;

import java.util.HashSet;
import java.util.Set;

public class lengthOfLongestSubstring {                                                //暴力法

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String k = "abcabcbbdsgfedshgdrsfgdsfgssssdgewrqwerqewrsadfdsafdsafafddsafdsafdsafrwqer";
        lengthOfLongestSubstring l = new lengthOfLongestSubstring();
        System.out.println(l.lengthOfLongestSubstring(k));
    }
    public int lengthOfLongestSubstring(String s) {
        int ans = 0;
        for(int i=0;i<s.length();i++)
            for(int j=i+1;j<=s.length();j++) 
                if (ifallUnique(s,i,j)) 
                    ans = Math.max(ans, j - i);
        return ans;
        
    }
    
    public boolean ifallUnique(String s, int start, int end) {                        //判斷是否唯一
        Set<Character> set = new HashSet<>();
        for (int i = start; i < end; i++) {
            Character ch = s.charAt(i);
            if (set.contains(ch)) return false;
            set.add(ch);
        }
        return true;
    }
}

上面一個我講的很細了,也很好理解,然後講一講時間複雜度小一點的 假設給定子串s[i,j],還是新增字元

若重複:記錄此時滑動視窗大小,並與最大滑動視窗比較,賦值。然後滑動視窗大小重定義為1,右移一個單位。

若不重複:滑動視窗頭不變,結尾+1,整個視窗加大1個單位,繼續比較下一個。

package Arithmetic;

import java.util.HashSet;
import java.util.Set;

public class lengthOfLongestSubstring2 {

    public static void main(String[] args) {
        String k = "2314fdssafewqroiqwue4riu2qjrkewhfu1y243985yrejhfskjdsahgfasjdhf98q2wy9rhewqkfhdsafhjdsahgfuasdrhdkjsh8327484y3(*^(*^%#$&^%#";
        // TODO Auto-generated method stub
        lengthOfLongestSubstring2(k);
        
    }
     public static int lengthOfLongestSubstring2(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++));
                }
            }
            System.out.println(ans);
            return ans;
        }
}

你以為到這裡就結束了,不!下面上python3的,以下程式碼也可以直接執行

class lengthOfLongestSubstring:

    def lengthOfLongestSubstring(self, s):
        start = 0
        max_length = 0
        substring = {}
        for i, j in enumerate(s):
            if j in substring and start <= substring[j]:          # 如果在子串裡
                start = substring[j] + 1                          # 視窗向後滑動一個
            else:
                max_length = max(max_length, i - start + 1)            
            substring[j] = i
        print(max_length)
        return max_length


if __name__ == '__main__':
    xxx = lengthOfLongestSubstring()
    xxx.lengthOfLongestSubstring('3sssfsdfsrdsxn;k[45dfsfdsfdfewrewfsfadsfaewrwrewrewrs')

    初始化了一個例項,enumerates函式是用來遍歷序列中的元素以及它們的下標