思路一:找到以每一个字符为结尾的所有最长不重复子字符串
- 从左到右,从第一个字符串开始,循环遍历判断下一个字符是否存在于前面的字符串里
- 如果不存在则增加当前字符串的长度,继续
- 如果存在,则说明当前字符"a"有重复,则定位到字符串中重复的字符"a"的位置,从字符串中"a"的位置的下一项开始到下一个字符"a"的位置形成以第二个a为结尾的最长不重复子串
- 从字符串中"a"位置开始到结尾的字符串,递归
结果:内存超限
代码:
class Solution
{
/**
* @param String $s
* @return Integer
*/
function lengthOfLongestSubstring($s)
{
$m = -1;
$s_array = str_split($s, 1);
for ($i = 0; $i < sizeof($s_array) - 1; $i++) {
$arr = array_slice($s_array, $m + 1, $i - $m);
if (array_search($s_array[$i + 1], $arr) !== false) {
$m = array_search($s_array[$i + 1], $arr);
$length = sizeof($arr);
$strsub = substr($s, $m + 1);
return $this->lengthOfLongestSubstring($strsub) > $length ? $this->lengthOfLongestSubstring($strsub) : $length;
}
}
return strlen($s);
}
}
第一个方案不管加多少break条件都会超限;放弃!
思路二:对字符串进行不断分割
想法是:最长子串一定出现在某两个重复字符串的中间
- 找出字符串中重复次数最多的字符,根据该字符对字符串进行拆分
- 拆分字符"x"的左右两边+"x"进行合并拼接成一个新的不重复"x"的子串
- 对拼接结果的子串递归上面的步骤
结果:204 ms 15.4 MB;性能很差
代码:
class Solution
{
/**
* @param String $s
* @return Integer
*/
function lengthOfLongestSubstring($s)
{
$max = 0;
$s_arr = count_chars($s, 1);
$m = max($s_arr);
if ($m == 1) {
$max = strlen($s);
} else {
$key_asc = array_search($m, $s_arr);
$key = chr($key_asc);
$s_split = explode($key, $s);
$s_list = [];
for ($i = 0; $i < sizeof($s_split) - 1; $i++) {
$s_temp = $s_split[$i] . $key . $s_split[$i + 1];
$s_list[] = $s_temp;
}
foreach ($s_list as $ss) {
$max_num = $this->lengthOfLongestSubstring($ss);
$max = $max_num > $max ? $max_num : $max;
}
}
return $max;
}
}
看来递归是行不通了,考虑迭代
思路三:同思路一,使用迭代方式找到以每个字符结尾的最长不重复子串
- 从左到右,从第二个字符串开始,循环遍历判断下一个字符是否存在于前面的字符串里
- 如果不存在,则增加当前字符串的长度,继续
- 如果存在,则说明当前字符"a"有重复,找到以第二个"a"结尾的最长不重复子串;更新迭代判断的初始位置为第一个"a"的下一个位置
- 遍历到下一个字符
结果:20 ms 16.2 MB
代码:
class Solution
{
/**
* @param String $s
* @return Integer
*/
function lengthOfLongestSubstring($s)
{
if (empty($s)) {
return 0;
}
$s_array = str_split($s, 1);
$former = 1;
$max = 1;
for ($i = 1; $i < strlen($s); $i++) {
$former = $former + 1;
for ($j = $i - $former + 1; $j < $i; $j++) {
if ($s_array[$j] == $s_array[$i]) {
$former = $i - $j;
break;
}
}
$max = $max > $former ? $max : $former;
}
return $max;
}
}