标签:
问题描述:
Given a string, find the length of the longest substring without repeating characters.
样例:
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.
看到这题我第一想法还是暴力解,再稍微考虑一下觉得暴力虽然可以解,但绝对不会是最优的。结果一番考虑后我决定采用队列解这道题。
int lengthOfLongestSubstring(char* s) { int front=0,rear=-1,i,j; int queue[100000]; int max=0; for(i=0;s[i]!=‘\0‘;i++){ queue[++rear]=s[i]; for(j=front;j<rear&&queue[rear]!=queue[j];j++) ; if(j<rear){ max=(max>=(rear-front))?max:(rear-front); front=j+1; } } if(rear-front+1>max) max=rear-front+1; return max; }
一开始我只给队列分配了5000个单元,越界了,再给10000还是越界,我一怒之下就给了100000,额,比较好的办法应该是把队列写成循环队列吧。
说说结果,顺利AC,击败60%的C提交,唔,算及格了。
但还是不够快,每次都要扫描一遍队列以确定有没有重复的字符太浪费时间了,这种情况用哈希表应该更快吧。不对!一个char型最多也就256,ASCII码总共只有127个,一个直接映射表就可以搞定了,还要啥哈希表!
typedef struct node{ int index; int number; }node; int lengthOfLongestSubstring(char* s) { node bucket[127]; int i,j,max=0,left=0; for(i=0;i<127;i++){ bucket[i].index=-1; bucket[i].number=0; } for(i=0;s[i]!=‘\0‘;i++){ if(bucket[s[i]].index>=left&&bucket[s[i]].number==1){ max=i-left>max?i-left:max; left=bucket[s[i]].index+1; } bucket[s[i]].index=i; bucket[s[i]].number=1; } max=i-left>max?i-left:max; return max; }
讲道理这都已经是O(n)的算法了,然而结果并不比上一个队列实现的算法快甚至更慢,仔细一考虑,因为ASCII码表只有127个字符,所以每次队列扫描都不会超过127次,上面的那个算法也可以看作是O(n)的算法,难怪速度提升不明显。
诶,这我就比较好奇了,其他人是怎样写出更高效的算法的,于是我打开官方给的solution,然而给出的最快的O(n)算法也是用的直接映射表。那就算了,想要再继续优化这个算法基本上只能考虑常数项了。
Longest Substring Without Repeating Characters问题
标签:
原文地址:http://www.cnblogs.com/evilkant/p/5932457.html