查找最长子串的长度(不重复字符)

给定一个字符串,找到最长子串的长度,而不重复字符。

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

例子:

给定"abcabcbb"的答案是"abc",长度是3。

给定"bbbbb"的答案是"b",长度为1。

给定"pwwkew"的答案是"wke","kew",长度为3。


暴力法,最好想,先记录一个最大值,挨个遍历每个字符,找出重复的字符就从下一个字符接着遍历,更新最大值,最后遍历完成后,最大值就是最长的子串长度了. 暴力法的时间复杂度是O(n^2).

/// 暴力枚举,
void fun1() {
    
    NSString * s = @"abcdafhgh";
    // 把单个字符放到数组里
    NSMutableArray * array = [NSMutableArray array];
    for (int i =0 ; i<s.length; i++) {
        NSString * temp = [s substringWithRange:NSMakeRange(i, 1)];
        [array addObject:temp];
    }
    
    int maxLength = 0;
    for (int i=0; i<array.count; i++) {
        // 用字典判断是否重复
        NSMutableDictionary * dic = [[NSMutableDictionary alloc] init];
        int j=i;
        for (; j<array.count; j++) {
            
            NSString * s = dic[ array[j] ] ;
            if (s==nil) {
                dic[ array[j] ] = @"1";
                continue;
            }
            break;
        }
        // 到这说明一件重复了,记录下最长的数据
        maxLength = MAX(maxLength, dic.count);
        NSLog(@"长度为 : %d %@",dic.count,dic);
        // j==array.count,说明遍历到最后了,这个值就是最大值了
        if (j==array.count) {
            break;
        }
    }
    NSLog(@"最大长度为 : %d",maxLength);
    
}

跳步处理,记录一个最大值,挨个遍历每个字符,找出重复的字符就从重复字符的下一个开始遍历, 

来个例子就懂了, 比如"axhchg",从a开始,遇到了第二个h,发现了重复, 暴力法的解决就是记录最大值"axhc",然后下一个从"x"往下找.

跳步处理,发现了重复,找到那个重复元素第一次出现的位置,然后从重复元素的下一个开始,在例子中就是从"c"开始处理,把前面的给跳过了. 这样处理后,跳步法的时间复杂度就是O(n)了.

class Solution {
    func lengthOfLongestSubstring(_ s: String) -> Int {
        
        if s.count <= 1 {
            return s.count
        }
 
        // 用数组做一个hash表,效率会高点,
        // 下标key是对应的字符的asciiValue,value是最近一次出现的位置
        var dic = Array(repeating: -1, count: 128)
        // 把字符串转成Int数组
        let keyArray = s.unicodeScalars.map { Int($0.value) }
        
        // 记录本次字符串开始的位置,
        var startIndex = 0
        var maxLength = 0
        
        for (i,item) in keyArray.enumerated() {
            // 找出此字符的最近出现位置
            let value = dic[item]
            // 如果出现过,更新startIndex, 没出现过startIndex不用动
            startIndex = max(value+1, startIndex)
            // 此字符的最近一次出现位置更新
            dic[item] = i
            maxLength = max(i-startIndex+1, maxLength)
 
        }
 
        return maxLength
    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值