博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Longest Substring Without Repeating Characters
阅读量:2425 次
发布时间:2019-05-10

本文共 2128 字,大约阅读时间需要 7 分钟。

题目

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

Examples:

Given "abcabcbb", the answer is"abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", 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.

分析

这道题目就是给你一个字符串,然后让你求出该字符串中最长的子串,该子串不包含重复的字符。

要想求出符合要求的最长子串,一般来说历遍整个字符串是必须的。那么,我们如何判断某个子串中的字符是否重复呢?

我们可以记录已经包含在子串中的字符,然后每添加一个新的字符,就与我们的记录相比较,这样就只要有没有重复了。在这里我新建了一个长度为256的数组用于记录已经包含在子串中的字符,下标对应字符的ASCII值,值对应字符在字符串(原始字符串)中的位置。初始化为-1,这样我们就可以根据数组的值来判断是否重复。

解决了判断重复的问题之后,如果出现了重复的,我们又该怎么办呢?

这时我们就可以用一个变量来记录子串第一个字符在给出的字符串中的位置。当发现重复之后,就更新子串第一个字符的位置,使得子串中没有重复的字符。更新后的子串第一个字符的位置应该是之前重复字符的位置加一。同时更新记录表中该重复字符的位置。

例如:对于字符串 abcdbaef。在遍历到第五个字符b的时候,之前我们记录的字符以及其位置如下(位置从0开始)

字符 a b c d
位置 0 1 2 3
由于字符b出现在记录表中,因此更新子串第一个字符的位置为 array[b] + 1 = 2。该位置为字符 c 所在的位置。字符表中b的位置更新为4。

注意:我们在更新子串第一个字符的位置之后,没有把记录表中小于该位置的字符去掉,因此记录表中有些字符不属于我们更新之后的子串。所以在判断重复的时候,如果某字符在记录表中记录的位置小于子串第一个字符的位置,直接更新该字符的位置就可以,不需要更新子串第一个字符的位置。例如上面遍历到第二个a的时候,由于a记录的位置为 0 < 2 ,直接更新 a 的位置为5即可。

在遍历的过程中,我们要记录当前子串的长度和已经找到的子串的最大长度。

代码

class Solution {public:    int lengthOfLongestSubstring(string s) {        // cur_len 为当前子串的长度, temp表示字符的ASCII值, valid表示当前子串第一个字符的位置,        // max_len 为已经找到的子串的最大长度        int cur_len = 0, temp, valid = 0, max_len = 0;        int characters[256];  // 记录每个字符所在的位置,就是上面所说的记录表        for (int i = 0; i < 256; i++) {            characters[i] = -1;        }        for (int i = 0; i < s.length(); i++) {            temp = s[i];            // 记录字符的位置,若重复,则更新字符的位置。            if (characters[temp] == -1) {        	characters[temp] = i;        	cur_len++;            } else if (characters[temp] >= valid) {		valid = characters[temp] + 1;  // 更新子串中第一个字符的位置		characters[temp] = i;		max_len = max_len > cur_len ? max_len : cur_len;		cur_len = i - valid + 1;            } else {                characters[temp] = i;        	cur_len++;            }        }        max_len = max_len > cur_len ? max_len : cur_len;        return max_len;    }};

其实,在更新子串中第一个字符位置的时候,可以将已经找到的最大子串的长度与剩下子串的长度作比较,以此来确定是否继续遍历字符串。

转载地址:http://pibmb.baihongyu.com/

你可能感兴趣的文章
OpenGL坐标系
查看>>
MySQL分布式集群之MyCAT(三)rule的分析
查看>>
不定期更新的碎碎念
查看>>
MySQL之SQL分析三部曲
查看>>
使用 COM+ 参数化对象结构编程技术 (转)
查看>>
C++(转载) (转)
查看>>
More effective C++ 条款12 (转)
查看>>
高可用性的HDFS—Hadoop分布式文件系统深度实践
查看>>
编程语言实现模式
查看>>
思考的乐趣:Matrix67数学笔记
查看>>
谁将主导世界货币?即将到来的新一轮全球危机
查看>>
数论概论(英文版.第4版)
查看>>
exceptional c++:47个c++工程难题、编程问题和解决方案(中文版)
查看>>
黎曼猜想漫谈
查看>>
CRM基础教程
查看>>
内存数据管理(第2版)
查看>>
深入理解Android:卷II
查看>>
QTP自动化测试最佳实践
查看>>
捉虫日记
查看>>
jQuery Mobile权威指南
查看>>