leetcode Longest Substring Without Repeating Characters

PS1:我想到一个好的方法去实现下面说的那个find函数,而且确定是常数时间:

对这个题目我的思想是从第一个字符往后找,知道找到在之前字符串中有出现的字符,这样的话,从出现的那个位置后的一个位置开始继续新的查找。现在有一个问题就是s.find()这个函数的时间复杂度是O(1)还是O(n)如果是O(1)的话那我这个算法就是O(n)的时间复杂度,如果是O(n)的话那就是O(n2)了。

代码:

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 int lengthOfLongestSubString(string s)
 6 {
 7     if (s.length() == 0)
 8         return 0;
 9     int max = 1;
10     int j = 0;
11     for (int i = 1; i < s.length(); i++)
12     {
13         int t = s.find(s[i], j);
14         if (t == i)
15         {
16             int temp = i - j + 1;
17             if (temp > max)
18                 max = temp;
19         }
20         else if (t < i)
21         {
22             j = t + 1;
23         }
24     }
25     return max;
26 }
27 
28 int main()
29 {
30     string s = "abcabcbb";
31     cout << lengthOfLongestSubString(s) << endl;
32 }

 这个题其实我写的是不好的,但我不知道在leetcode上看到的那个结局问题用的时间上,我竟然是Cpp里面比较好的,挺神奇的一定是那个find特别效果特别好,要不然就是测试数据不是很厉害。

更好的代码:

 1 int lengthOfLongestSubstring(string s) {
 2   int n = s.length();
 3   int i = 0, j = 0;
 4   int maxLen = 0;
 5   bool exist[256] = { false };
 6   while (j < n) {
 7     if (exist[s[j]]) {
 8       maxLen = max(maxLen, j-i);
 9       while (s[i] != s[j]) {
10         exist[s[i]] = false;
11         i++;
12       }
13       i++;
14       j++;
15     } else {
16       exist[s[j]] = true;
17       j++;
18     }
19   }
20   maxLen = max(maxLen, n-i);
21   return maxLen;
22 }

这里就是用到了一个数据先暂存已经出现的字母,但是虽然他没有用find函数,但是由于里层的while循环同样可以做到找到已出现的并且循环后的i就是那个位置。这是一个好的代码。

我提交了一下这个代码发现和我的代码时间消耗几乎是一样的。费解!

原文地址:https://www.cnblogs.com/chaiwentao/p/4313937.html