作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
公众号:负雪明烛
本文关键词:无重复字符,最长子串,题解,leetcode, 力扣,python, c++, java


题目地址:https://leetcode.com/problems/longest-substring-without-repeating-characters/description/

题目描述

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", which the length is 3.

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

题目大意

找出字符串中最长的不含有重复字符的子串长度。

解题方法

看见题目求长度的,一般时间复杂度都不会太高。

解法一:虫取法+set

所谓虫取法,就是根据某个条件交替移动前后指针,使得在双指针之内的这部分是满足题意要求的。

具体思路比较简单易懂,使用双指针,[left, right]双闭区间来保存子串的左右区间,对应着这个区间我们维护一个set,这个set里面全部是不重复的字符。

使用while循环,如果right字符不在set中,就让它进去;如果right在,就把left对应的字符给remove出去。

所以,当我们得到一个right位置的字符时,通过移动left和修改[left,right]区间内对应的的set,来保持了一个最小的不重复字符区间。这里需要注意的是,移动left的次数不一定就是1次,因为我们要保证left和right之间没有重复字符,而新添加的right字符出现的位置不一定刚刚就是left指向的位置。

比如:

a b c b b c b b
0 1 2 3 4 5 6 7

当right移动到3的时候字符时b,此时,set = {a, b, c}中,left=0,字符b在set中。

所以在while循环中反复移动left,当left移动到2的位置时,此时set = {c},字符b已经不在set中。

按照这个方式移动,set的个数最多的值即为最长子串。

一定注意:[left, right]区间和set是对应的,要同时维护。

下面的python代码是根据right指向的字符是否出现在set中而反复的进行循环,代码如下:

class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
left, right = 0, 0
chars = set()
res = 0
while left < len(s) and right < len(s):
if s[right] in chars:
if s[left] in chars:
chars.remove(s[left])
left += 1
else:
chars.add(s[right])
right += 1
res = max(res, len(chars))
return res

下面的C++代码的思路是如果right刚移动到某个位置,而这个位置的字符在set中出现过,那么就内循环left使得right指向的元素不在set中为止。本质上和上面的代码一致。这里的代码是每次都要把right指向的元素放入到set中的。

class Solution {
public:
int lengthOfLongestSubstring(string s) {
const int N = s.size();
if (N <= 1) return N;
unordered_set<char> set;
int res = 0;
int l = 0, r = 0;
while (r < N) {
while (set.count(s[r])) {
set.erase(s[l]);
++l;
}
set.insert(s[r]);
res = max(res, int(set.size()));
++r;
}
return res;
}
};

方法二:一次遍历+字典

一次遍历时,使用字典保存每个字符第一次出现的位置。这个方法我一直不知道叫什么名字,就勉强叫做prefix方法吧,因为需要维护已经遍历到的前缀部分。

当right向后遍历的过程中,如果这个字符在字典中,说明这个字符在前面出现过,即这个区间已经不是题目要求的不含重复字符的区间了,因此,需要移动left。

移动left到哪里呢?有个快速的方法,那就是移动到right字符在字典中出现的位置(即s[right]在前面的位置)的下一个位置。

无论如何都会使用right更新字典,另外记录最大区间长度即为所求。

注意,left更新的时候需要保留最大(最右)的位置。举例说明:

对于abba,当right指向最后的a的时候,left指向的是字典中保留的有第一个位置的a,如果不对此进行判断的话,left会移动到第一个字符b。

left一定是向右移动的,不可能撤回到已经移动过的位置。

class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
left, right = 0, 0
res = 0
chars = dict()
for right in range(len(s)):
if s[right] in chars:
left = max(left, chars[s[right]] + 1)
chars[s[right]] = right
res = max(res, right - left + 1)
return res

C++代码如下,注意C++的变量务必需要初始化,否则将不确定,比如这里的l和res,如果不初始化会产生莫名其妙的结果:

class Solution {
public:
int lengthOfLongestSubstring(string s) {
const int N = s.size();
unordered_map<char, int> pos;
int l = 0;
int res = 0;
for (int r = 0; r < N; ++r) {
if (pos.count(s[r])) {
l = max(l, pos[s[r]] + 1);
}
pos[s[r]] = r;
res = max(res, r - l + 1);
}
return res;
}
};

参考资料:https://www.youtube.com/watch?v=hw0zHamgaks

另外有个文章不错:http://www.cnblogs.com/grandyang/p/4480780.html

日期

2018 年 8 月 24 日 —— Keep fighting!
2019 年 1 月 19 日 —— 有好几天没有更新文章了

【LeetCode】3. Longest Substring Without Repeating Characters 无重复字符的最长子串的更多相关文章

  1. 【LeetCode】Longest Substring Without Repeating Characters(无重复字符的最长子串)

    这道题是LeetCode里的第3道题. 题目描述: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: ...

  2. leetcode 3. Longest Substring Without Repeating Characters 无重复字符的最长子串

    一.题目大意 https://leetcode.cn/problems/longest-substring-without-repeating-characters/ 给定一个字符串 s ,请你找出其 ...

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

    Given a string, find the length of the longest substring without repeating characters. Example 1: In ...

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

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

  5. [leetcode]3. Longest Substring Without Repeating Characters无重复字母的最长子串

    Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...

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

    网址:https://leetcode.com/problems/longest-substring-without-repeating-characters/ 显然采用sliding window滑 ...

  7. Leetcode3.Longest Substring Without Repeating Characters无重复字符的最长字串

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

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

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

  9. [Swift]LeetCode3. 无重复字符的最长子串 | Longest Substring Without Repeating Characters

    Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...

随机推荐

  1. CentOS安装配置Hadoop 1.2.1(伪分布模式)

    CentOS安装配置Hadoop1.2.1 1.下载安装文件 下载2个安装文件 JAVA环境:jdk-6u21-linux-i586.bin Hadoop环境:hadoop-1.2.1.tar.gz ...

  2. Markdown-写作必备

    Markdown--入门指南 导语: Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdow ...

  3. 05 Windows安装python3.6.4+pycharm环境

    windows安装python3.6.4环境 使用微信扫码关注微信公众号,并回复:"Python工具包",免费获取下载链接! 一.卸载python环境 卸载以下软件: 二.安装py ...

  4. 巩固javaweb的第二十八天

    巩固内容: 设置页面的编码方式 实现代码: 每个 JSP 页面都需要设置编码方式,设置 JSP 页面的编码方式可以是下面两种方式 之一. 方式一: <%@ page contentType=&q ...

  5. typedef定义数组

    typedef定义数组 问题来源 在学习高一凡数据结构与算法解析串这一章节时,遇到如下代码不明白其意义,经过查阅终于搞明白 typedef unsigned char SString[MAXLEN + ...

  6. HTML 基本标签2

    HTML标题通过<h1>-<h6>标签定义(<h1>定义最大的标题,<h6>定义最小的标题) <html>用于定义HTML文档 HTML段落 ...

  7. A Child's History of England.17

    CHAPTER 6 ENGLAND UNDER HAROLD HAREFOOT, HARDICANUTE, AND EDWARD THE CONFESSOR Canute left three son ...

  8. 断言(assert)简介

    java中的断言assert的使用 一.assertion的意义和用法 J2SE 1.4在语言上提供了一个新特性,就是assertion功能,他是该版本再Java语言方面最大的革新. 从理论上来说,通 ...

  9. day9 图书设计项目

    总路由层url from django.conf.urls import url from django.contrib import admin from app01 import views ur ...

  10. Oracle中建表及表操作

    一.创建表 Oracle中的建表语句:create table 表名( 字段名1 数据类型 列属性,字段名2 数据类型 列属性,...... ) 如:创建表OA_DM.DM_GY_USER https ...