`
wangqisen
  • 浏览: 47219 次
文章分类
社区版块
存档分类
最新评论

LeetCode之Longest Substring Without Repeating Characters

 
阅读更多

Longest Substring Without Repeating Characters

AC Rate: 1774/7414
My Submissions

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

转自:http://blog.csdn.net/allen_fan_01/article/details/9034163

基本算法使用Hash

要求子串中的字符不能重复,判重问题首先想到的就是hash,寻找满足要求的子串,最直接的方法就是遍历每个字符起始的子串,辅助hash,寻求最长的不重复子串,由于要遍历每个子串故复杂度为O(n^2),n为字符串的长度,辅助的空间为常数hash[256]。代码如下:

  1. /*最长不重复子串设串不超过30
  2. *我们记为LNRS
  3. */
  4. intmaxlen;
  5. intmaxindex;
  6. voidoutput(char*arr);
  7. /*LNRS基本算法hash*/
  8. charvisit[256];
  9. voidLNRS_hash(char*arr,intsize)
  10. {
  11. for(inti=0;i<size;++i)
  12. {
  13. memset(visit,0,sizeof(visit));
  14. visit[arr[i]]=1;
  15. for(intj=i+1;j<size;++j)
  16. {
  17. if(visit[arr[j]]==0)
  18. {
  19. visit[arr[j]]=1;
  20. }else
  21. {
  22. if(j-i>maxlen)
  23. {
  24. maxlen=j-i;
  25. maxindex=i;
  26. }
  27. break;
  28. }
  29. }
  30. }
  31. output(arr);
  32. }

DP方案

前面刚刚讨论过最长递增子序列的问题,咋一想就觉得二者有点类似,何不向DP方面想一下,为什么说二者类似,在LIS问题中,对于当前的元素,要么是与前面的LIS构成新的最长递增子序列,要么就是与前面稍短的子序列构成新的子序列或单独构成新子序列;

同理,对于最长不重复子串,某个当前的字符,如果它与前面的最长不重复子串中的字符没有重复,那么就可以以它为结尾构成新的最长子串;如果有重复,那么就与某个稍短的子串构成新的子串或者单独成一个新子串。

举个例子:例如字符串“abcdeab”,第二个字符a之前的最长不重复子串是“abcde”,a与最长子串中的字符有重复,但是它与稍短的“bcde”串没有重复,于是它可以与其构成一个新的子串,之前的最长不重复子串“abcde”结束;

再看一个例子:字符串“abcb”,跟前面类似,最长串“abc”结束,第二个字符b与稍短的串“c”构成新的串;

这两个例子,可以看出些眉目:当一个最长子串结束时(即遇到重复的字符),新的子串的长度是与(第一个重复的字符)的下标有关的。

于是类似LIS,对于每个当前的元素,我们“回头”去查询是否有与之重复的,如没有,则最长不重复子串长度+1,如有,则是与第一个重复的字符之后的串构成新的最长不重复子串,新串的长度便是当前元素下标与重复元素下标之差。

于是我们得到O(N^2)的DP方案,我们可以与LIS的DP方案进行对比,是一个道理的。代码如下:

  1. /*LNRSdp*/
  2. intdp[30];
  3. voidLNRS_dp(char*arr,intsize)
  4. {
  5. inti,j;
  6. maxlen=maxindex=0;
  7. dp[0]=1;
  8. for(i=1;i<size;++i)
  9. {
  10. for(j=i-1;j>=0;--j)
  11. {
  12. if(arr[j]==arr[i])
  13. {
  14. dp[i]=i-j;
  15. break;
  16. }
  17. }
  18. if(j==-1)
  19. {
  20. dp[i]=dp[i-1]+1;
  21. }
  22. if(dp[i]>maxlen)
  23. {
  24. maxlen=dp[i];
  25. maxindex=i+1-maxlen;
  26. }
  27. }
  28. output(arr);
  29. }

DP + Hash方案

上面的DP方案是O(n^2)的,之所以是n^2,是因为“回头”去寻找重复元素的位置了,受启发于最初的Hash思路,我们可以用hash记录元素是否出现过,我们当然也可以用hash记录元素出现过的下标,既然这样,在DP方案中,我们何不hash记录重复元素的位置,这样就不必“回头”了,而时间复杂度必然降为O(N),只不过需要一个辅助的常数空间visit[256],典型的空间换时间。

代码如下:这样遍历一遍便可以找到最长不重复子串

  1. /*LNRSdp+hash记录下标*/
  2. voidLNRS_dp_hash(char*arr,intsize)
  3. {
  4. memset(visit,-1,sizeofvisit);//visit数组是-1的时候代表这个字符没有在集合中
  5. memset(dp,0,sizeofdp);
  6. maxlen=maxindex=0;
  7. dp[0]=1;
  8. visit[arr[0]]=0;
  9. for(inti=1;i<size;++i)
  10. {
  11. if(visit[arr[i]]==-1)//表示arr[i]这个字符以前不存在
  12. {
  13. dp[i]=dp[i-1]+1;
  14. visit[arr[i]]=i;/*记录字符下标*/
  15. }else
  16. {
  17. dp[i]=i-visit[arr[i]];
  18. }
  19. if(dp[i]>maxlen)
  20. {
  21. maxlen=dp[i];
  22. maxindex=i+1-maxlen;
  23. }
  24. }
  25. output(arr);
  26. }


DP + Hash优化方案

写到这里,还是有些别扭,因为辅助的空间多了,是不是还能优化,仔细看DP最优子问题解的更新方程:

1

dp[i] = dp[i-1] + 1;

dp[i-1]不就是更新dp[i]当前的最优解么?这与最大子数组和问题的优化几乎同出一辙,我们不需要O(n)的辅助空间去存储子问题的最优解,而只需O(1)的空间就可以了,至此,我们找到了时间复杂度O(N),辅助空间为O(1)(一个额外变量与256大小的散列表)的算法,代码如下

  1. /*LNRSdp+hash优化*/
  2. voidLNRS_dp_hash_impro(char*arr,intsize)
  3. {
  4. memset(visit,-1,sizeofvisit);
  5. maxlen=maxindex=0;
  6. visit[arr[0]]=0;
  7. intcurlen=1;
  8. for(inti=1;i<size;++i)
  9. {
  10. if(visit[arr[i]]==-1)
  11. {
  12. ++curlen;
  13. visit[arr[i]]=i;/*记录字符下标*/
  14. }else
  15. {
  16. curlen=i-visit[arr[i]];
  17. }
  18. if(curlen>maxlen)
  19. {
  20. maxlen=curlen;
  21. maxindex=i+1-maxlen;
  22. }
  23. }
  24. output(arr);
  25. }




分享到:
评论

相关推荐

    LeetCode3 Longest Substring Without Repeating Characters

    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...

    javalruleetcode-LeetCode:LeetCode算法问题

    java lru leetcode Fighting for a job! 记录找工作期间搬运的题,全部使用Java实现,本人C++鶸 1 ...LeetCode ...LeetCode ...LeetCode ...LeetCode ...Characters LeetCode 13 Roman to Integer LeetCode 6 Zi

    leetcode答案-LeetCode-Longest_Substring_Without_Repeating_Characters:Leet

    答案LeetCode-Longest_Substring_Without_Repeating_Characters 这是LeetCode上“最长子串无重复字符”问题的解决方案。 问题描述:给定一个字符串,求没有重复字符的最长子串的长度。 示例 1:输入:“abcabcbb” ...

    leetcode分类-leetcode:leetcode问题的代码

    leetcode 分类leetcode 问题分类 leetcode代码仓库,我的解题思路写在我的博客里: leetcode 代码库,我博客上的解题思路: mkdir 列表: 大批 #1:Two Sum #4:Median of Two Sorted Arrays 地图 #1:Two Sum #3:...

    程序员面试宝典LeetCode刷题手册

    3. Longest Substring Without Repeating Characters 4. Median of Two Sorted Arrays 7. Reverse Integer 9. Palindrome Number 11. Container With Most Water 13. Roman to Integer 15. 3Sum 16. 3Sum Closest 17...

    leetcodepython001-leetcode:https://leetcode.com/的解决方案

    leetcode Python 001 力码 ├── Algorithms │  ├── cpp │  │  ├── 001 - Two Sum.cpp │  │  ├── 002 - Add Two Numbers.cpp │  │  ├── 003 - Longest Substring Without Repeating ...

    leetcode卡-LeetCode:我的LeetCode解决方案

    leetcode卡 LeetCode 记录一下再LeetCode上刷的题,坚持每天刷一道吧 2017.06.12 打卡[LeetCode 2. Add Two Numbers], Linked list 2017.06.13 打卡[LeetCode 200. Number of Islands], BFS 2017.06.14 打卡...

    leetcode2sumc-LeetCode-3.Longest_Substring_Without_Repeating_Characters

    LeetCode-3.Longest_Substring_Without_Repeating_Characters 给定一个字符串,找出没有重复字符的最长子字符串的长度。 示例 1: 输入:“abcabcbb” 输出:3 解释:答案是“abc”,长度为 3。 解决方案 Python3:...

    lrucacheleetcode-leetcode:leetcode

    lru缓存leetcode leetcode 1. Two Sum 2. Add Two Numbers 3. Longest Substring Without Repeating Characters 4. Median of Two Sorted Arrays 5. Longest Palindromic Substring 7. Reverse Integer 9. ...

    leetcode分类-leetcode:leetcode

    leetcode 分类 Leetcode Introduction 本文旨在将leetcode的题型分类 Pattern: Sliding window 滑动窗口类型的题目经常是用来执行数组或是链表上某个区间(窗口)上的操作。比如找最长的全为1的子数组长度。滑动窗口...

    leetcode双人赛-LeetCode:力扣笔记

    leetcode双人赛LeetCode 编号 题目 难度 题型 备注 Two Sum 简单 Add Two Numbers 中等 链结串列 重要 Longest Substring Without Repeating Characters 中等 字串 重要 Median of Two Sorted Arrays 困难 数学 ...

    leetcode题库-LeetCode-Go:用GO回答LeetCode

    leetcode题库 LeetCode-Go 理论基础 见Note 脑图 TODO 待填充 算法题 面试高频出现,以及一些非常经典重要的算法题优先 题目列表 No Title Link Solution Acceptance Difficulty Topics Solution 0001 Two Sum 46.1%...

    dna匹配leetcode-leetcode:leetcode刷题

    Longest Substring Without Repeating Characters 哈希表 双指针 滑动窗口 Substring with Concatenation of All Words 哈希表 注意匹配方向 Valid Sudoku 数组 遍历 Sudoku Solver 深度优先遍历 回溯 先检查后修改 ...

    leetcode中文版-LeetCode:LeetcodeC++/Java

    leetcode中文版 LeetCode # Title Chinese Tag Solution 1 Two Sum 两数之和 array,hash 2 Add Two Numbers 两数相加 math 3 Longest Substring Without Repeating Characters 无重复字符的最长子串 string 4 ...

    leetcode338-LeetCode:LeetCode刷题总结

    LeetCode刷题总结 1.Two Sum 2.Add Two Numbers 3.Longest Substring Without Repeating Characters 4.Median of Two Sorted Arrays 5.Longest Palindromic Substring (Manacher算法待完成) 6.ZigZag Conversion 7....

    分割数组求最大差值leetcode-Leetcode-Road:LeetCode刷题记录

    学习之路 记录自己完成LeetCode的代码和结果。 序号 中文名称 英文名称 通过率 难度 1 Two Sum 47.0% 简单 2 Add Two Numbers 36.0% 中等 3 Longest Substring Without Repeating Characters 32.0% 中等 4 Median of...

    javalruleetcode-Leetcode:力码解决方案

    (两数之和) Easy Hash Table 2 Add Two Numbers (两数相加) Medium Linked List 3 Longest Substring Without Repeating Characters (无重复字符的最长子串) Medium Dual Pointer (Sliding Window), Hash Table 4 ...

    javalruleetcode-leetcode-java:力码笔记

    Without Repeating Characters 5.Longest Palindromic Substring 20.Valid Parentheses 26.Remove Duplicates from Sorted Array 53.Maximum Subarray 70.Climbing Stairs 121.Best Time to Buy and Sell Stock 122....

    Leetcode回文串拼接-leetcode_note:用于记录leetcode题目的解析

    Leetcode回文串拼接 leetcode_node 题解 该项目主要用于基于Leetcode的刷题记录,与日常学习,对Leetcode上的题目按照解题方法进行分明别类的整理。 题目列表 1.Two Sum 2.Add Two Numbers 3.Longest Substring ...

    leetcode题库-leetcode-web:以Web形式展示LeetCode题解,基于PythonFlask

    leetcode题库 LeetCode-Web 初始化 前端库依赖 下载,并将jquery-3.x.x.min.js移动到static目录下。 下载,并将semantic.min.js、semantic.min.css、components和themes...longest-substring-without-repeating-charac

Global site tag (gtag.js) - Google Analytics