力扣获取最大无重复字符子串长度C语言实现

该博客介绍了如何使用C语言解决力扣的最大无重复字符子串长度问题。通过滑动窗口和ASCII码映射,优化了双层循环,达到高效求解。文章总结了代码实现的关键点,包括记录字符出现状态、移动窗口和更新子串长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

力扣获取最大无重复字符子串长度C语言实现

最大无重复字符子串长度问题-C语言实现

给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
输入: s = “abcabcbb”
输出: 3

解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
输入: s = “aaaa”
输出: 1
解释: 因为无重复字符的最长子串是 “a”,所以其长度为 1。

代码实现


int lengthOfLongestSubstring(char * s){
   int sLen = strlen(s);
    int left = 0, ret = 0, cnt = 0;
    int right;
    int tmp[128] = {0};//记录某个字符是否已经出现过一次
    
    for(right = 0; right < sLen; right++){
        if(0 == tmp[s[right]])//右滑动窗口,如果有一个字符出现过则会进入else移动左窗
        { 
            tmp[s[right]]=1;//记录这个字符是否出现了
            cnt++;//窗口长度,也即子串长度
            if(cnt > res){
                ret = cnt;//ret用来记录找到过的最大无重复子串长度
            }
        }
        else//左滑动窗口,字符有重复,需要找到这个字符
        {
        	/*左窗移动,清空字符记录,直到找到跟右窗口相同的这个字符。
        	* 一旦需要移动左窗时,就意味着当前右窗的字符在当前左右窗所匹配到的子串中出现过。
        	* 因此需要移动左窗来找到这个重复字符,并且将左窗当前字符记录清空,
        	* 以便进入下一轮循环的if判断中,右窗来确认左窗已经找到这个字符。
        	*/
            tmp[s[left]] = 0;//清空当前字符的记录,如果清空的是右窗所在的字符,那么下一轮循环一定会进入if内部移动右窗了。
            
            left++;//左窗移动到下一个
            cnt--;//左窗向右移动了,因此需要-1。
            right--;//进入下一轮for循环时,i会自动+1。因此此处-1保证右窗位置不变
        }
    }
    return ret;
}

思路

  1. ASCII码每个字符唯一,因此可以用tmp[128]数组来记录当前字符是否出现了(简化的hash table);
  2. 滑动窗口:利用双指针索引子串;
  3. 判断条件:for循环用来移动右窗。假设右窗是可移动的,那么我们需要一直移动右窗,当右窗所在字符前面出现过,那就必须要开始处理左窗来剔除掉这个重复字符,当左窗剔除了这个字符,我们才能继续移动右窗;
  4. 合理的控制循环体变量能等效于另一个有效for循环;

总结

这个leetcode题目用常规的两层for循环也可以解决问题,但是刷到了评论中一位高手的优化代码。有意思的点在于在循环体中更改循环变量,用来实现第二次for循环。在正常工作中编写代码时,是不建议的循环体中修改循环变量,但是对于代码优化上还是有一定帮助,因此以此作为笔记学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值