難度: 中等php
Given a string, find the length of the longest substring without repeating characters. 給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。java
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。優化
示例 2:
輸入: "bbbbb" 輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。this
示例 3:
輸入: "pwwkew" 輸出: 3 解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。spa
示例 4:
輸入: "dvdf"
輸出: 3
解釋: 由於無重複字符的最長子串是 "vdf",因此其長度爲 3。注意不是2。code
一、定義一個方法 isUnique($s, $start, $end)
給定字符串和開始、結束標識,計算裏面是否包含重複字符,若是是返回false,不然true。 二、對字符串s
遍歷 i*j
趟,生成字串使用isUnique
判斷是否是重複,若是不是,則更新 返回值 max(最長子串 的長度)。索引
至關於遍歷 N^3次:leetcode
//判斷一個字符串裏面是否有重複字符 function isUnique($s, $start, $end) { $map = []; $len = $end-$start+1; $sub_str = substr($s, $start, $len); for ($i = 0; $i < $len; $i++) { if (in_array($sub_str[$i], $map) ) { return false; } $map[] = $sub_str[$i]; } return true; } /** * @param String $s * @return Integer */ function lengthOfLongestSubstring($s) { $len = strlen($s); $max = 0; if ($len > 0) { $max = 1; } for ($i = 0; $i < $len; $i++) { for ($j = $i + 1; $j < $len; $j++) { if ($this->isUnique($s, $i, $j)) { if ($j - $i + 1 > $max) { $max = $j - $i + 1; } } } } return $max; }
時間複雜度爲O(n^3)。字符串
上面的暴力解法實在是太慢了。以字符串ababc
爲例,ab
出現了2次,那麼對於子串aba
、abab
、ababc
的計算是能夠省略的,能夠將i
直接日後移動。get
咱們能夠使用一個集合(Set)存儲遍歷過的值,若是發現即將要遍歷的字符串已經存在set裏,那麼能夠將i
直接日後移動,並將已存在的字符從集合裏刪除;若是發現即將要遍歷的字符串不在set裏,則放在set裏,並將j
日後移動,同時更新返回值 max(最長子串 的長度)。
function lengthOfLongestSubstring2($s) { $len = strlen($s); $max = 0; $i = $j = 0; $set = []; while ($i< $len && $j < $len) { if (!in_array($s[$j], $set)) { $set[] = $s[$j++]; $max = max($max, $j - $i); } else { //出現過,說明符合要求的子字符串已經結束,刪掉子字符串開始的字符 //因爲php沒有java的hashSet結構,下面是模擬刪除set裏的值 unset($set[array_keys($set, $s[$i++])[0]]); } } return $max; }
時間複雜度爲O(2n)=O(n)。
function lengthOfLongestSubstring3($s) { $len = strlen($s); $max = 0; $i = $j = 0; $map = []; //dvdf while ($i< $len && $j < $len) { if (array_key_exists($s[$j], $map)) { //發現重複字符,key移動到不重複字符的位置 //例如dvdf,第三次發現d,已經重複,第一個的d的索引是0,那麼i須要往下移動 $i = max($map[$s[$j]] + 1, $i); } $map[$s[$j]] = $j; //key存儲字符,value存儲某個不重複字符的索引 $max = max($max, $j - $i + 1); $j++; } return $max; }
連接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters