问题描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
分析
这个问题使用动态规划法对问题进行结构
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
这个问题实际上是属于多阶段决策问题。
前两个字符没有重复 -> 判断连上第三个字符是否重复 -> 不重复就增加一位,然后继续判断下一个;重复则结束,返回字符串
每个阶段的判断方式都是一样的,可以抽象出来。
function compare($s,$i){
$str = $s[$i]; //return $str;
$j = $i - 1 ;
while($j >= 0 && !strstr($str,$s[$j])){
$str.=$s[$j];
$j -=1;
}
return strlen($str);
}
上面把判断的阶段抽象了出来,那么再通过判断状态,找到最长的返回值,就得到了结果。
解
class Solution {
/**
* @param String $s
* @return Integer
*/
function lengthOfLongestSubstring($s) {
if($s == ""){ //判断空字符串
return 0;
}
$len = 0;
for($i=0;$i < strlen($s);$i++){
$len = max($len, $this->compare($s, $i));
}
return $len;
}
//比较
function compare($s,$i){
$str = $s[$i]; //return $str;
$j = $i - 1 ;
while($j >= 0 && !strstr($str,$s[$j])){
$str.=$s[$j];
$j -=1;
}
return strlen($str);
}
}
执行用时 : 236 ms , 在所有 PHP 提交中击败了 20.56% 的用户
内存消耗 : 15 MB , 在所有 PHP 提交中击败了 65.45% 的用户
参考资料
- https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
- https://baike.baidu.com/item/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92