用 PHP 来刷leetCode 之 无重复字符 最长子串

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ty5622022/article/details/88039373

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

示例 1:

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

示例 2:

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

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 

"wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

方法一:暴力法

思路

逐个检查所有的子字符串,看它是否不含有重复的字符。

$str = "";
function lengthOfLongestSubstring($s) {
    $strlen = strlen($s);
    if($strlen<=1){
        return $strlen;
    }
    $subStrlen = [];

    for($i=0;$i<$strlen;$i++){
        $subStrArr = [];
        $subStrArr[] = $s[$i];
        for($j=$i+1;$j<$strlen;$j++){
            $subStrArr[] = $s[$j];
            if(count(array_unique($subStrArr))!=count($subStrArr)){
                array_pop($subStrArr);
                break;
            }

        }
        $subStrlen = count($subStrArr)>count($subStrlen)?$subStrArr:$subStrlen;
    }
    return count($subStrlen);
}
$a = lengthOfLongestSubstring($str);
print_r($a);

输出2

方法二

暴力法非常简单。但它太慢了。那么我们该如何优化它呢?

我们可以利用类似滑动窗口的方法

如果从索引 i 到 j - 1 之间的子字符串s[i,j)已经被检查为没有重复字符。我们只需要检查 s[j] 对应的字符是否已经存在于子字符串 s[i,j)​ 中。

function lengthOfLongestSubstring($s) {
        $len = strlen($s);
        if ($len < 2){
            return $len;
        }
        $win = [];
        $res_len = 0;
        $i = 0;
        $j = 0;
        while ($i<$len && $j<$len){
            if(!in_array($s[$i],$win)){
                $win[]= $s[$i++];
                $res_len = max($res_len,$i-$j);

            }else{
                $j++;
                array_shift($win);
            }
        }
        return $res_len;
    }

嗯 简单试了一下 差不多是上面方法的20倍 并且随着字符串的长度增长会更大  因为他是O(n)  

方法三:优化版滑动窗口

上述的方法最多需要执行 2n 个步骤。事实上,它可以被进一步优化为仅需要 n 个步骤。我们可以定义字符到索引的映射 当我们找到重复的字符时,我们可以立即跳过该窗口。

也就是说,如果 s[j] 在 [i, j) 范围内有与 j' 重复的字符,我们不需要逐渐增加 i 。 我们可以直接跳过 [i,j'] 范围内的所有元素,并将 i变为 j' + 1。

  function lengthOfLongestSubstring($s)
    {
        $len = strlen($s);
        $j = 0;
        $i = 0;
        $maxStrLen = 0;
        $set = [];
        while ($j<$len){
            if(array_key_exists($s[$j],$set)){
                $i = max($i,$set[$s[$j]]);

            }
            $maxStrLen = max($maxStrLen,$j-$i+1);
            $set[$s[$j]]=$j+1;
            $j++;
        }
        return $maxStrLen;
    }

猜你喜欢

转载自blog.csdn.net/ty5622022/article/details/88039373