字符串中的无重复最长子串
题目
给定ascii字符串 s ,找出最长不重复子串。 要求时间复杂度为O(n)。
 例:      s = "abcdadefg"  => max_sub_uniq_str = "adefg"
分析
方法1
设置两个索引: 当前子串开始索引 cur_begin, 和当前字符索引 index, 针对当前字符s[index],
查找区间 【 s[cur_begin], s[index] )是否存在字符s[index]字符。
如果不存在, index++,继续一个字符;
如果存在需要回溯处理:
m1: cur_begin++, index = cur_begin + 1; 这样处理肯定会浪费了以前的比较处理结果;
m2 : cur_begin 从重复字符下一个位置开始,比如 s = "Abcbagh" , 当cur_begin = 0, index = 3时
s[1] = s[3] = b. 1为重复字符的索引,cur_begin = 1 + 1 = 2 开始。
无论m1 还是 m2, 时间复杂度肯定不是O(n)。
方法2:
由于是ascii字符串, 那么字符串中包含的不重复字符最多有256个。
使用一个包含256个元素数组marks,记录各个字符出现在字符串中的索引。marks[x] 的值大于当前子串的开始索引,
那么说明 子串 【 s[cur_begin], s[index])中包含 s[index]字符,此时, cur_begin = marks[s[index]] + 1,
该方法不需要回溯,时间复杂度为O(n),空间复杂度为 为常数。
代码
1 #include <stdio.h> 2 #include <string.h> 3 void print(const char *s, int start, int last) { 4 int i = start; 5 printf("sub_str s = %d e = %d :", start, last); 6 if(i == -1) 7 return 8 for( ; i <= last; i++) { 9 printf("%c", s[i]); 10 } 11 printf("\n\n"); 12 } 13 14 int find_max_uniq_sub_str(const char *s, int *start, int *last) { 15 int max_begin = 0; // max sub str start index 16 int max_end = 0; // max sub str end index 17 int cur_begin = 0; // 当前子串的开始索引 18 int marks[256] = { -1 }; 19 int index = 0; 20 int temp_idx = 0; 21 int exist_dup = 0; 22 if(s == NULL || start == NULL || last == NULL) 23 return -1; 24 // -1 every byte is -1 25 memset(flags, -1, sizeof(flags)); 26 while(s[index]) { 27 temp_idx = s[index]; 28 if( marks[ temp_idx ] >= cur_begin ) { 29 // [cur_begin, index] 中, s[flags[ temp_idx ] = s[index] 30 exist_dup = 1; 31 if( (index - cur_begin) > (max_end + 1 - max_begin) ) { 32 // [cur_begin, index) 与 [begin, end] 区间的大小 33 max_begin = cur_begin; 34 max_end = index - 1; 35 } 36 print(s, max_begin, max_end); 37 cur_begin = marks[ temp_idx ] + 1; // 更新当前子串的起始位置 38 } 39 flags[ temp_idx ] = index++; 40 } 41 if(!exist_dup) { // 无重复 42 max_end = index-1; 43 } 44 *start = max_begin; 45 *last = max_end; 46 return 0; 47 } 48 int main(int argc, const char*argv[]) { 49 int start = -1; 50 int last = -1; 51 printf("argv[1] = %s\n", argv[1]); 52 find_max_uniq_sub_str(argv[1], &start, &last); 53 print(argv[1], start, last); 54 return 0; 55 }
                    
                
                
            
        
浙公网安备 33010602011771号