无重复字符的最长子串

无重复字符的最长子串

思路一:找到以每一个字符为结尾的所有最长不重复子字符串

  1. 从左到右,从第一个字符串开始,循环遍历判断下一个字符是否存在于前面的字符串里
    1. 如果不存在则增加当前字符串的长度,继续
    2. 如果存在,则说明当前字符"a"有重复,则定位到字符串中重复的字符"a"的位置,从字符串中"a"的位置的下一项开始到下一个字符"a"的位置形成以第二个a为结尾的最长不重复子串
  2. 从字符串中"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条件都会超限;放弃!

思路二:对字符串进行不断分割

想法是:最长子串一定出现在某两个重复字符串的中间

  1. 找出字符串中重复次数最多的字符,根据该字符对字符串进行拆分
  2. 拆分字符"x"的左右两边+"x"进行合并拼接成一个新的不重复"x"的子串
  3. 对拼接结果的子串递归上面的步骤

结果: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;
    }
}

看来递归是行不通了,考虑迭代

思路三:同思路一,使用迭代方式找到以每个字符结尾的最长不重复子串

  1. 从左到右,从第二个字符串开始,循环遍历判断下一个字符是否存在于前面的字符串里
    1. 如果不存在,则增加当前字符串的长度,继续
    2. 如果存在,则说明当前字符"a"有重复,找到以第二个"a"结尾的最长不重复子串;更新迭代判断的初始位置为第一个"a"的下一个位置
  2. 遍历到下一个字符

结果: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;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值