Leetcode题目3—无重复字符的最长子串(C实现)

3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

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

示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

题目链接

头脑风暴:一般情况下遍历最长无重复子串是逐个字符遍历“a”ok、“ab”ok、“abc”ok、“abca”warning!重复了,“b”ok、“bc”ok、“bca”ok、“bcab”warning!重复了…
发现规律:

  • 逐个遍历
  • 一旦发现重复,遍历回退到已存在的重复字符的后一个位置

思路:hash表+滑动窗口

  • slidingWindowQeueu将s字符值作为index,每遍历的的字符在hash中标记:该字符的位置+1
  • 若head遍历到的字符存在在hash中存在要分两种情况讨论:
    • 该字符已存在在窗口内,需要调整窗口,将窗口左侧移动到hash中的位置。
    • 该字符已存在在窗口外,不需要调整窗口。
  • 更新滑动窗口大小
  • 检查此时窗口大小是否最大,若为最大窗口值,更新max的值
int lengthOfLongestSubstring(char * s){
    int max = 0;//字符串的最长长度
    int ret = 0;//用于滑动窗口大小

    int head = 0;//窗口右侧指针
    int rear = 0;//窗口左侧指针
    int slidingWindowQeueu[128] = {0};

    if(strlen(s) == 0)
    return 0;

    while(head <= strlen(s) - 1)
    {
        if(slidingWindowQeueu[s[head]] )//窗口右指针指向的字符已存在
        {
            rear = slidingWindowQeueu[s[head]] > rear ? slidingWindowQeueu[s[head]] : rear ;
            //若此字符已存在在窗口外,不作处理。若此字符已存在在窗口内,则滑动窗口,使窗口左侧位置设置为hash中的值。
        }
        ret = head - rear + 1;//记录此次遍历时的窗口大小
        max = ret > max ? ret : max;//记录最大的窗口大小
        slidingWindowQeueu[s[head]] = head +1;//记录此字符出现的位置的前一个位置
        head++;//前移
    }
    return max;
}

转载大神
执行用时 :4 ms, 在所有 C 提交中击败了95.17%的用户
内存消耗 :7.1 MB, 在所有 C 提交中击败了80.73%的用户
时间复杂度O(n),空间复杂度O(n)

int lengthOfLongestSubstring(char * s){
    int prior = 0; //上次状态下最长子串的长度
    int left = 0;
    int dict[256] = {0}; //映射ASCII码
    int right = 1; //表示字符串中第right个字符
    int i;

    while(*s != '\0'){
        i = *s-0; //字符转换为整数
        if(dict[i] > left)    
            left = dict[i];
        dict[i] = right;
        prior = (prior>right-left)?prior:right-left; //right的值比对应的数组下标大1
        s++;
        right++;
    }
    return prior;
}

作者:jack-153
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/3wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-jack-1/
来源:力扣(LeetCode)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值