难度: 中等

题目

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

Leetcode——3. 无重复字符的最长子串的更多相关文章

  1. Leetcode(三)无重复字符的最长子串

    3. 无重复字符的最长子串 题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最 ...

  2. 【LeetCode】无重复字符的最长子串【滑动窗口法】

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc&quo ...

  3. [LeetCode] 3. 无重复字符的最长子串

    题目链接:(https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/) 题目描述: 给定一个字符 ...

  4. 【leetcode 3. 无重复字符的最长子串】解题报告

    思路:滑动窗口的思想 方法一:滑动窗口 int lengthOfLongestSubstring(string s) { /* 控制一个滑动窗口,窗口内的字符都是不重复的,通过set可以做到判断字符是 ...

  5. LeetCode 3: 无重复字符的最长子串 Longest Substring Without Repeating Characters

    题目: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. Given a string, find the length of the longest substring withou ...

  6. 力扣Leetcode 3. 无重复字符的最长子串

    无重复字符的最长子串 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串 ...

  7. [LeetCode]3. 无重复字符的最长子串(滑动窗口)

    题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc ...

  8. [LeetCode]3.无重复字符的最长子串(Java)

    原题地址: longest-substring-without-repeating-characters/submissions 题目描述: 示例 1: 输入: s = "pwwkew&qu ...

  9. LeetCode 3. 无重复字符的最长子串(Longest Substring Without Repeating Characters)

    题目描述 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. ...

随机推荐

  1. ios、安卓的兼容性

    日期转换成时间戳: 安卓下可以使用 Date.parse(new Date('2019-11-18 12:00:00')) 直接转换,结果为 1574049600000 ios下 Date.parse ...

  2. HTTP协议,到底是什么鬼?

    作者 | Jeskson 来源 | 达达前端小酒馆 了解HTTP HTTP是什么呢?它是超文本传输协议,HTTP是缩写,它的全英文名是HyperText Transfer Protocol. 那么什么 ...

  3. [LeetCode] 552. Student Attendance Record II 学生出勤记录之二

    Given a positive integer n, return the number of all possible attendance records with length n, whic ...

  4. [LeetCode] 190. Reverse Bits 颠倒二进制位

    Reverse bits of a given 32 bits unsigned integer. Example 1: Input: 00000010100101000001111010011100 ...

  5. js实现一键复制

    方法一: 使用插件 引入clipboard.js 使用如下 <script> copyFn = function() { var clipboard = new Clipboard('.c ...

  6. 判断一个类型是否为可空类型 System Nullable

    bool IsNullableType(Type theType)  {      return (theType.IsGenericType && theType.        G ...

  7. Swagger简单介绍

    一句话介绍 Swagger Swagger是一个接口文档生成工具,同时提供接口测试调用的辅助功能. 关于 Swagger Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原 ...

  8. C# 使用ConcurrentBag类处理集合线程安全问题

    在日常的开发中,经常会遇到多个线程对同一个集合进行读写操作,就难免会出现线程安全问题. 以下代码,如果使用List<T>就会遇到问题:System.InvalidOperationExce ...

  9. Unity Shader 2D水流效果

    水流的模拟主要运用了顶点变换和纹理动画的结合: 顶点变换中,利用正弦函数模拟河流的大致形态,例如波长,振幅等. 纹理动画中,将纹理坐标朝某一方向持续滚动以形成流动的效果. 脚本如下: Shader & ...

  10. linux搜索log文件的内容

    日志一般是记载每天所做的工作.在计算机科学中,日志是指服务器等电脑设备或软件的运作记录(Server log).在电脑设备和软件出现问题时,日志是我们在排查问题的一个重要依据.查询日志是用户记录从客户 ...