1. 程式人生 > >求最長不重複子串---LeetCode3

求最長不重複子串---LeetCode3

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.

本文參考http://blog.sina.com.cn/s/blog_a89440490102wqff.html 中第一個解法

Java 程式碼塊

public static int lengthOfLongestSubstring(String s) {
        char[] ch=s.toCharArray();
        if(ch.length==0)
            return 0;
        int init=0;//滑動視窗左邊界
        int tag=0;//滑動視窗右邊界
        int right=0;//最長字串左邊界
        int
len=1;//最長字串長度 HashMap map=new HashMap(); map.put(ch[0], 0); while(++tag<ch.length){ //如果出現重複字串 if(map.containsKey(ch[tag])){ //如果視窗長度超過len if((tag-init)>len){ right=init;//右邊界等於right len
=tag-init; } int num=(int) map.get(ch[tag]);//記錄重複字串第一次出現的下標 for(int i=init;i<num+1;i++){//移除移到視窗外的字元 map.remove(ch[i]); } map.put(ch[tag], tag);//更新該字元的下標為右邊界 init=num+1; }else{//對於不重複字串 map.put(ch[tag], tag); if(tag==ch.length-1){ if((tag - init + 1 )> len){ right=init; len=tag-init+1; // System.out.println(tag); } } } } return len; }

解釋:

1)若字串長度為0,則直接返回0;
2)若字串長度不為0,
init:代表滑動視窗左邊界
tag:代表滑動視窗右邊界,依次移動一位
right:最長子串左邊界
len:問題所求的最長不重複子串
採用滑動視窗的思想,用視窗將不重複字元的子串框住。儲存在hashmap中,滑動視窗的右邊界tag每次右移一位需要進行以下操作:
(1)判斷該字元是否存在於hashmap中:
a:已存在,則子串已達到最大長度(tag-init),將最大長度與最長子串len相比較,如果比之長,則更新最長子串長度(len=tag-init),同時視窗的左邊界(right)更新為重複字元首次(map.get(ch[tag]))出現的下標+1,並且將map中的字元移除;
b:不存在於map中,則將該字元新增到map中(map.put(ch[tag],tag)),然後判斷右邊界(tag)是否到達字串終點,如果已到達終點,則該子串也達到了最大長度,與最長子串長度比較,如果比之長,則更新最長子串。
遍歷完成後即求出了最長子串的長度。

注意:

(1)hashmap中儲存的是所有不重複子串及其下標;
(2)滑動視窗移動時首先進行的是判斷該字元是否存在於map中;
(3)當滑動視窗到達字串的末尾時,注意最長子串的長度的求法;
說明:第一次寫部落格,記錄LeetCode中的題目,也許寫的不好,希望可以堅持下去,不僅僅是堅持寫部落格,還有LeetCode中的題目。