这道题能算DP吗?那要看是否具备最优子结构。我的分析是没有明显的子结构性质。
例如当求下表为 i 的最长无重复子串时,要考虑两类情况。
(1) s[ i ] 是否在字符串s之前的位置出现过,如果没有则长度 len++ ;
(2) 如果出现过,分两种情况讨论(是否出出现在当前处理的子串中)(len表示当前处理的子串的长度)
a> 在。那好办,直接更新len = i - (出现位置下标) ;
b>不在。更好办,直接更新 len++。
分析可见,并没有什么最优子结构,DP也谈不上吧。
数据结构:
可采用C++11的unordered_map,这个可以再常数时间内找到某个元素(map的红黑树实现需要logn),但是否足够好?不然,数组更好,高级一点可用C++11的Array,还不用处理HASH冲突。所有的字符不过256而已。空间、时间都是一流的。
需要注意的用数组,一要清0,二要主要下标操作。下标不能从1开始,否则就无法判断第一个元素是否出现,会被默认为没有出现。举个例子:abcdaefghi,如果下标从0那么a的重复就不会发现,你得到的是整个序列的长度。
上篇的1000多个测试用例的时间为380MS,这里的为144MS,节省了一半还多。
int lengthOfLongestSubstring(string s) { if(s=="") return 0; array<int,256> map; map.fill(0); int len=0,maxLen=0; for(int i=0 ; i<s.size();++i){ if(map[s[i]]==0||i+1-len>map[s[i]]) // index should plus 1 to avoid 0 index len++; else len = i+1-map[s[i]];<span style="white-space:pre"> </span>// same reason map[s[i]]=i+1; <span style="white-space:pre"> </span>//start from 1 maxLen=max(len,maxLen); } return maxLen; }
时间: 2024-10-07 02:28:48