php无重复字符的最长子串,Leetcode——3. 无重复字符的最长子串

难度: 中等

题目

Given a string, find the length of the longest substring without repeating characters.

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"

输出: 1

解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

示例 4:

输入: "dvdf"

输出: 3

解释: 因为无重复字符的最长子串是 "vdf",所以其长度为 3。注意不是2。

PHP

暴力解法

1、定义一个方法 isUnique($s, $start, $end) 给定字符串和开始、结束标识,计算里面是否包含重复字符,如果是返回false,否则true。

2、对字符串s遍历 i*j趟,生成字串使用isUnique判断是不是重复,如果不是,则更新 返回值 max(最长子串 的长度)。

相当于遍历 N^3次://判断一个字符串里面是否有重复字符

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直接往后移动。function lengthOfLongestSubstring($s) {

$len = strlen($s);

$max = 0;

$i = $j = 0;

$map = [];

while ($i< $len && $j < $len) {

if (!in_array($s[$j], $map)) {

$map[] = $s[$j ];

$max = max($max, $j - $i);

} else {

//出现过,说明符合要求的子字符串已经结束,删掉子字符串开始的字符

unset($map[$i ]);

}

}

return $max;

}

优化的滑动窗口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;

}

你可能感兴趣的:(php无重复字符的最长子串)