算法集

【iOS每日算法】无重复字符的最长子串(滑动窗口):给定一个字符

2020-09-17  本文已影响0人  CoderRocker_Axl

题目:

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

考察点:

解法:

一、暴力查找(我最开始想到的解法)

- (NSInteger)checkTheString:(NSString *)content {
    NSInteger length = content.length;
    for (NSInteger i = length; i > 0; i--) {
        // i为子串长度
        for (NSInteger j = 0; j + i <= length; j++) {
            // 从0开始截取长度为i的子串
            NSRange range = NSMakeRange(j, i);
            NSString *rangeString = [content substringWithRange:range];
            NSMutableDictionary *letterDic = [[NSMutableDictionary alloc]init];
            // 循环遍历子串,如果有重复的字符结束循环,移动子串位置,如果没有重复字符return当前子串长度
            for (NSInteger c = 0; c < rangeString.length; c++) {
                NSRange letterRange = NSMakeRange(c, 1);
                NSString *letter = [rangeString substringWithRange:letterRange];
                if([[letterDic allKeys] containsObject:letter]) {
                    break;
                } else {
                    [letterDic setValue:@"1" forKey:letter];
                }
                if(c == rangeString.length - 1) {
                    return i;
                }
            }
        }
    }
    return 1;
}

二、滑动窗口法
- (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];
        // 判断是否含有滑动加入的字符
        if([[checkedDict allKeys]containsObject:letter]) {
            // 如果有将记录子串起始位置的start移动到该字符之前出现的位置的下一个位置
            // 相当于把左边指针向右拉,直到不包含当前遍历的字符,这样这个子串中就没有重复字符了
            start = [[checkedDict objectForKey:letter] integerValue] + 1;
            NSInteger tempLength = i - start + 1;
            // 毕竟子串长度,取最长的
            if(tempLength > maxLength) {
                maxLength = tempLength;
            }
        }
        // 更新子串中该字符位置
        [checkedDict setObject:@(i) forKey:letter];
    }
    return maxLength;
}

总结

思考

上一篇 下一篇

猜你喜欢

热点阅读