美文网首页
无重复字符的最长子串(滑动窗口)

无重复字符的最长子串(滑动窗口)

作者: Queen_BJ | 来源:发表于2020-10-22 15:43 被阅读0次
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
-(NSInteger )getAlgfirstString:(NSString *)content
{
//    NSString *content = @"afdsdssscscdv";
    NSInteger lenth = content.length;
    
    for (NSInteger i = lenth; i > 0; i--) {
        
        // i 为子串长度
        for (NSInteger j = 0; j+i <= lenth; j++) {
            
            // 从0开始截取长度为i的子串
            NSRange range = NSMakeRange(j, i);
            NSString *rangeString = [content substringWithRange:range];
            NSMutableDictionary *letterDic = [[NSMutableDictionary alloc]init];
            
            NSLog(@"j == %ld, i == %ld,rangeString = %@",j,i,rangeString);
            
            // 循环遍历子串,如果有重复的字符串结束循环,移动子串位置,如果没有重复字符return当前子串长度
            for (NSInteger c = 0; c < rangeString.length; c++) {
                
                NSRange letterRange = NSMakeRange(c, 1);
                NSString *letter = [rangeString substringWithRange:letterRange];
                
                NSLog(@"letter == %@",letter);
                
                if ([[letterDic allKeys]containsObject:letter]) {
                    
                    NSLog(@"letterDic == %@",letterDic);
                    break;
                    
                }else{
                    
                    [letterDic setValue:@"1" forKey:letter];
                }
                
                if (c == rangeString.length - 1) {
                    
                    NSLog(@"i == %ld",i);
                    
                    return i;
                }
            }
        }
    }
}

 2020-10-20 17:22:20.727952+0800 ThreadDemo[2137:188852] j == 0, i == 8,rangeString = wshdtbsd
     2020-10-20 17:22:20.728094+0800 ThreadDemo[2137:188852] letter == w
     2020-10-20 17:22:20.728217+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.728311+0800 ThreadDemo[2137:188852] letter == h
     2020-10-20 17:22:20.728417+0800 ThreadDemo[2137:188852] letter == d
     2020-10-20 17:22:20.728506+0800 ThreadDemo[2137:188852] letter == t
     2020-10-20 17:22:20.728601+0800 ThreadDemo[2137:188852] letter == b
     2020-10-20 17:22:20.728695+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.728873+0800 ThreadDemo[2137:188852] letterDic == {
         b = 1;
         d = 1;
         h = 1;
         s = 1;
         t = 1;
         w = 1;
     }
     2020-10-20 17:22:20.729276+0800 ThreadDemo[2137:188852] j == 0, i == 7,rangeString = wshdtbs
     2020-10-20 17:22:20.729585+0800 ThreadDemo[2137:188852] letter == w
     2020-10-20 17:22:20.729904+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.730240+0800 ThreadDemo[2137:188852] letter == h
     2020-10-20 17:22:20.730505+0800 ThreadDemo[2137:188852] letter == d
     2020-10-20 17:22:20.730799+0800 ThreadDemo[2137:188852] letter == t
     2020-10-20 17:22:20.731096+0800 ThreadDemo[2137:188852] letter == b
     2020-10-20 17:22:20.731363+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.731674+0800 ThreadDemo[2137:188852] letterDic == {
         b = 1;
         d = 1;
         h = 1;
         s = 1;
         t = 1;
         w = 1;
     }
     2020-10-20 17:22:20.731980+0800 ThreadDemo[2137:188852] j == 1, i == 7,rangeString = shdtbsd
     2020-10-20 17:22:20.737182+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.737297+0800 ThreadDemo[2137:188852] letter == h
     2020-10-20 17:22:20.737400+0800 ThreadDemo[2137:188852] letter == d
     2020-10-20 17:22:20.737495+0800 ThreadDemo[2137:188852] letter == t
     2020-10-20 17:22:20.737594+0800 ThreadDemo[2137:188852] letter == b
     2020-10-20 17:22:20.737686+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.737798+0800 ThreadDemo[2137:188852] letterDic == {
         b = 1;
         d = 1;
         h = 1;
         s = 1;
         t = 1;
     }
     2020-10-20 17:22:20.737897+0800 ThreadDemo[2137:188852] j == 0, i == 6,rangeString = wshdtb
     2020-10-20 17:22:20.738115+0800 ThreadDemo[2137:188852] letter == w
     2020-10-20 17:22:20.738385+0800 ThreadDemo[2137:188852] letter == s
     2020-10-20 17:22:20.738655+0800 ThreadDemo[2137:188852] letter == h
     2020-10-20 17:22:20.738961+0800 ThreadDemo[2137:188852] letter == d
     2020-10-20 17:22:20.739270+0800 ThreadDemo[2137:188852] letter == t
     2020-10-20 17:22:20.739548+0800 ThreadDemo[2137:188852] letter == b
     2020-10-20 17:22:20.739844+0800 ThreadDemo[2137:188852] i == 6
     2020-10-20 17:22:20.740179+0800 ThreadDemo[2137:188852] 非重复长度- 6
二、滑动窗口法
  • 我们使用两个指针表示字符串中的某个子串(的左右边界)
  • 在每次循环检查向右移动右指针,检查右指针指向的字符在之前是否有重复
  • 如无重复,记录下长度并将该字符的index为值,该字符为key存入字典中。
  • 如有重复,则将左指针,指向子串中上一个该字符的下一个字符(这样最新的左指针到右指针就没有重复字符)
  • 同时更新该字符在字典中的位置,将该字符的index为值,该字符为key存入字典中。
  • 计算次字符串长度,并与之前无重复字符串长度比对,如果本次更长,则更新最长长度,最后return
  • 时间复杂度O(n)只需循环一次字符串
- (NSInteger)checkTheStringScan:(NSString *)content {
    NSInteger length = content.length;
    // 记录已经遍历过的字符所在位置的字典
    NSMutableDictionary *checkedDict = [[NSMutableDictionary alloc]init];
    NSInteger maxLength = 0;
    //记录子串起始位置的指针
    NSInteger start = 0;
    // 循环字符串 i 为右边指针,不断向右移动,像一个往右划的窗口
    for (NSInteger i = 0; i < length ; i++) {
        NSRange letterRange = NSMakeRange(i, 1);
        NSString *letter = [content substringWithRange:letterRange];
        
        NSLog(@"letter == %@ ",letter);
        // 判断是否含有滑动加入的字符
        if([[checkedDict allKeys]containsObject:letter]) {
            // 如果有将记录子串起始位置的start移动到该字符之前出现的位置的下一个位置
            // 相当于把左边指针向右拉,直到不包含当前遍历的字符,这样这个子串中就没有重复字符了
            
            NSLog(@"checkedDict == %@,[checkedDict allKeys] = %@",checkedDict,[checkedDict allKeys]);
            
            start = [[checkedDict objectForKey:letter] integerValue] + 1;
            NSInteger tempLength = i - start + 1;
            
            NSLog(@"start == %ld ,tempLength = %ld",start,tempLength);
            
            // 毕竟子串长度,取最长的
            if(tempLength > maxLength) {
                maxLength = tempLength;
                
                NSLog(@"maxLength == %ld ",maxLength);
            }
        }
        // 更新子串中该字符位置
        [checkedDict setObject:@(i) forKey:letter];
    }
    return maxLength;
}

2020-10-20 17:48:58.979685+0800 ThreadDemo[2241:204126] letter == w
2020-10-20 17:48:58.979819+0800 ThreadDemo[2241:204126] letter == s
2020-10-20 17:48:58.979934+0800 ThreadDemo[2241:204126] letter == h
2020-10-20 17:48:58.980096+0800 ThreadDemo[2241:204126] letter == d
2020-10-20 17:48:58.980215+0800 ThreadDemo[2241:204126] letter == t
2020-10-20 17:48:58.980407+0800 ThreadDemo[2241:204126] letter == b
2020-10-20 17:48:58.980667+0800 ThreadDemo[2241:204126] letter == s
2020-10-20 17:48:58.981013+0800 ThreadDemo[2241:204126] checkedDict == {
    b = 5;
    d = 3;
    h = 2;
    s = 1;
    t = 4;
    w = 0;
},[checkedDict allKeys] = (
    d,
    w,
    b,
    s,
    h,
    t
)
2020-10-20 17:48:58.981414+0800 ThreadDemo[2241:204126] start == 2 ,tempLength = 5
2020-10-20 17:48:58.981848+0800 ThreadDemo[2241:204126] maxLength == 5
2020-10-20 17:48:58.981949+0800 ThreadDemo[2241:204126] letter == d
2020-10-20 17:48:58.982339+0800 ThreadDemo[2241:204126] checkedDict == {
    b = 5;
    d = 3;
    h = 2;
    s = 6;
    t = 4;
    w = 0;
},[checkedDict allKeys] = (
    d,
    w,
    b,
    s,
    h,
    t
)
2020-10-20 17:48:58.982739+0800 ThreadDemo[2241:204126] start == 4 ,tempLength = 4
2020-10-20 17:48:58.983180+0800 ThreadDemo[2241:204126] 非重复长度- 5

参考简书

相关文章

网友评论

      本文标题:无重复字符的最长子串(滑动窗口)

      本文链接:https://www.haomeiwen.com/subject/bwgdmktx.html