Leetcode3.无重复字符的最长子串 - 两种方式

3最长无重复子串导图

食用指南:

Leetcode专栏开启了,由于博主闭关期末,所以每日只能一题
尽量做到一题多解,先说思路,之后代码实现,会添加必要注释
语法或STL内容会在注意点中点出,新手友好
欢迎关注博主神机百炼专栏,内涵算法基础详细讲解和代码模板

题目描述:

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

    s 由英文字母、数字、符号和空格组成

  • 代码背景

class Solution {
public:
    int lengthOfLongestSubstring(string s) {

    }
};
  • 题目来源:https://leetcode.cn/problems/longest-substring-without-repeating-characters/submissions/

题目分析:

  • 经典滑动窗口

  • 法一:自己实现字符串内字符数目记录数组

    由于所有出现的字符都在ASCII码表当中,

    所以开一个Hash[128]就可以记录ASCII表中所有可见字符出现次数

  • 法二:STL的unordered_map实现字符记录

    unordered_map具有泛型<类型1,类型2>

    利用字符char为键,出现次数为值

    unmap[s[i]]就是字符s[i]的出现次数
    需要注意区分unmap.find()和此处出现次数unmap[s[i]]的区别

算法模板:

代码实现:

  • 滑动窗口本身最差时间复杂度就是i j两指针都走了一遍s
  • 最差时间复杂度O(2n)

法一:unordered_map<>

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = 0;
        unordered_map<char, int> Hash;
        for(int i=0, j=0; j<s.size(); j++){
            Hash[s[j]]++;
            while(Hash[s[j]] > 1) Hash[s[i]]--, i++;
            len = max(len, j-i+1);
        }
        return len;
    }
};

法二:Hash[128]

  • ASCII码表中可见字符都在前128个
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = 0;
        int Hash[128];
        memset(Hash, 0, sizeof(Hash));
        for(int i=0, j=0; j<s.size(); j++){
            Hash[s[j]-' ']++;
            while(Hash[s[j]-' '] > 1) Hash[s[i]-' ']--, i++;
            len = max(len, j-i+1);
        }
        return len;
    }
};

注意点:

1. ASCII码表常识:

  • ASCII码表中共有256个字符

    但是可见的字符都在前128个

    可见字符以空格space’ '的ASCII码值最小,为32

  • 空字符串长度为1,因为\0结尾

2. unmap.count() 和 unmap[s[i]]的区别:

  1. unmap[s[i]]的s[i]是key,是哈希表索引
    unmap[s[i]]本身是value,是哈希表内值
  2. unmap.count(key)是说哈希表中这个key有没有对应的value
    有则返回1,没有返回0
  3. 所以说s = “aa”;
    unmap[s[0]] == unmap[s[1]] == 2;

    unmap.count(s[0]) == unmap.count(s[1]) == 1;
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starnight531

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值