zoukankan      html  css  js  c++  java
  • 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次,那么对于子串abaababababc的计算是可以省略的,可以将i直接往后移动。

    我们可以使用一个集合(Set)存储遍历过的值,如果发现即将要遍历的字符串已经存在set里,那么可以将i直接往后移动,并将已存在的字符从集合里删除;如果发现即将要遍历的字符串不在set里,则放在set里,并将j往后移动,同时更新返回值 max(最长子串 的长度)。

    function lengthOfLongestSubstring2($s) {
        $len = strlen($s);
        $max = 0;
        $i = $j = 0;
        $set = [];
    
        while ($i< $len && $j < $len) {
            if (!in_array($s[$j], $set)) {
                $set[] = $s[$j++];
                $max = max($max, $j - $i);
            } else {
                //出现过,说明符合要求的子字符串已经结束,删掉子字符串开始的字符
                //由于php没有java的hashSet结构,下面是模拟删除set里的值
                unset($set[array_keys($set, $s[$i++])[0]]);
            }
        }
    
        return $max;
    }
    

    时间复杂度为O(2n)=O(n)。

    优化的滑动窗口

    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;
    }
    

    来源

    链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters

  • 相关阅读:
    关于多态的一些问题
    003 关于shell基础,大数据的前期准备
    002 在大数据中基础的llinux基本命令
    013 MapReduce八股文的wordcount应用
    接口里语句的修饰问题
    Apache Rewrite url重定向功能的简单配置
    学习笔记 --- 缓存、动态页面静态化、网站优化
    使用PHP连接、操纵Memcached的原理和教程
    Apache中关于页面缓存的设置
    缓存(之一) 使用Apache Httpd实现http缓存
  • 原文地址:https://www.cnblogs.com/52fhy/p/11032882.html
Copyright © 2011-2022 走看看