【string】hash table, two pointers, string

利用hash table, two pointers, string的题目。

1.求最长不重复子串的长度

hash table体现在一个数组,下标是字符串中元素的ASCII值,下标对应的元素代表该元素在字符串中出现的位置。

two pointers体现在用i一步步向前移去遍历字符串中的元素,作为不重复子串的末尾位置;用j指向不重复字符区间的首字符的位置。

 1 /***************************
 2 @date 4.23
 3 @description   https://leetcode.com/problems/longest-substring-without-repeating-characters/
 4 Given a string, find the length of the longest substring without repeating characters.
 5 For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3.
 6 For "bbbbb" the longest substring is "b", with the length of 1.
 7 @tags: hash table, two pointers, string
 8 用一个0~255的数组,数组下标是字符的ASCII值,数组里的内容初始化都为-1,表现未出现。
 9 当其在字符串中出现,则赋值为当前字符在字符串中的下标;
10 变量i代表不重复字符区间末端的位置;j代表不重复字符区间第一个字符的位置;
11 当第一次出现重复字符时,该下标对应的值肯定是比j要大,此时将j赋值为该下标的后一位num[s[i]] + 1, i继续向前移,j<i
12 每次计算连续不重复字符的个数,并将其与max_len对比
13 ******************************/
14 
15 #include <iostream>
16 #include <string>
17 #include <memory.h>
18 using namespace std;
19 
20 class Solution{
21 public:
22     int lengthOfLongestSubstring(string s){
23         int max_len = 0, len = 0;
24         int num[256];
25         memset(num, -1, sizeof(num)); // 初始化为-1,表示没有出现过
26         for (int i = 0, j = 0; i < s.size(); ++i){
27             if (num[s[i]] < j)
28                 len = i - j + 1;    // 统计连续不重复字符的个数
29 
30             else   // 如果第二次出现
31                 j = num[s[i]] + 1;
32             if (max_len < len)
33                 max_len = len;
34            num[s[i]] = i;
35         }
36         return max_len;
37     }
38 
39 };
40 
41 
42 int main(){
43     Solution a;
44     cout << a.lengthOfLongestSubstring("abcdefgabcdefgh");
45 }

2.子串变位词

hash table体现在一个数组,下标是字符串中字符的ASCII-'a',相当于0~25;下标对应的元素表示该字符出现的次数。

动态维护一个子串长度的窗口,a[i-lenb+1]~a[i]

 1 /*********************
 2 @date 4.22
 3 @description
 4 给定两个串a和b,问b是否是a的子串的变位词。(假设只含有全英的小写字母a~z)
 5 例如输入a = hello, b = lel, lle, ello都是true,但是b = elo是false。
 6 @tags: string, hash table, two pointers
 7 
 8 ********************/
 9 
10 #include <iostream>
11 #include <string>
12 
13 using namespace std;
14 
15 class Solution{
16 public:
17     bool subStringAnagram(string a, string b){
18         int nonZero = 0;
19         int num[26] = {0};
20         int lena = a.size();
21         int lenb = b.size();
22 
23         if (lena < lenb)
24             return;
25 
26         for (int i = 0; i < lenb; i++)
27             if (++num[b[i] - 'a'] == 1) ++nonZero; // nonZero 有多少个字符非0次出现
28 
29 
30         for (int i = 0; i < lenb; ++i){   // 第一个窗口单独开,因为第一个窗口的第一个元素不能丢
31             int c = a[i] - 'a';
32             --num[c];                       // 此时的num[]变成了a,b对应元素出现的次数的差值
33             if (num[c] == 0) --nonZero;
34             else if(num[c] == 1) ++nonZero;
35             if (nonZero == 0) return true;
36         }
37 
38         for(int i = lenb; i < lena; ++i){
39             int c = a[i-lenb] - 'a';
40             ++num[c]; // 扔掉a[i-lenb];   // 新窗口是a[i-lenb+1]...a[i]
41             if (num[c] == 1) ++nonZero;
42             else if(num[c] == 0) --nonZero;
43             c = a[i] - 'a';               // 旧窗口是a[i-lenb]....a[i-1]
44             --num[c]; // 加入a[i]
45             if (num[c] == 0) --nonZero;
46             else if(num[c] == -1) ++nonZero;
47             if (nonZero == 0) return true;
48         }
49     }
50 };
51 
52 
53 int main(){
54     Solution a;
55     cout << a.subStringAnagram("hello", "ell");
56 }
原文地址:https://www.cnblogs.com/cnblogsnearby/p/4451857.html