leetcode刷题Day3|无重复字符的最长字串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长 子串 的长度。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> m(128,0);
int a=0,b=0,ans=0;
for(int b=0;b<s.size();b++){
a=max(a,m[s[b]]);
m[s[b]]=b+1;
ans=max(ans,b-a+1);
}
return ans;
}
};
在这段代码中,m
是一个大小为 128 的整数数组,用于记录每个字符最后一次出现的位置。s
是输入的字符串,s[j]
是字符串 s
中的第 j
个字符。
m[s[j]]
的含义:
s[j]
是字符串s
中的第j
个字符。m[s[j]]
表示字符s[j]
最后一次出现的位置(索引 + 1)。
为什么是 m[s[j]]
:
- 由于字符在计算机中是以 ASCII 码表示的,
s[j]
可以看作是一个整数(ASCII 码值)。 m
数组的大小为 128,因为 ASCII 码的范围是 0 到 127。m[s[j]]
就是根据字符s[j]
的 ASCII 码值来访问数组m
中的对应位置。
代码中的具体作用:
-
i = max(i, m[s[j]]);
:m[s[j]]
记录了字符s[j]
最后一次出现的位置(索引 + 1)。i
表示当前无重复字符子串的起始位置。- 如果
s[j]
之前出现过,m[s[j]]
会大于i
,此时更新i
为m[s[j]]
,即跳过重复字符的位置。
-
m[s[j]] = j + 1;
:- 更新字符
s[j]
最后一次出现的位置为j + 1
(即当前字符的下一个位置)。 - 这样做的目的是为了在后续的遍历中,如果再次遇到
s[j]
,可以通过m[s[j]]
快速找到它的上一次出现位置。
- 更新字符
-
ans = max(ans, j - i + 1);
:- 计算当前无重复字符子串的长度
j - i + 1
,并与之前的最大长度ans
比较,更新ans
。
- 计算当前无重复字符子串的长度
总结:
m[s[j]]
用于记录字符s[j]
最后一次出现的位置,帮助我们在遍历字符串时快速找到重复字符的位置,从而更新无重复字符子串的起始位置i
。- 通过这种方式,代码能够高效地找到字符串中最长的无重复字符子串的长度。
vector<int> m(128, 0);
是 C++ 中定义并初始化一个 vector
的语句。下面详细解释它的含义:
1. vector<int>
:
vector
是 C++ 标准库中的一个动态数组容器,可以存储相同类型的元素。<int>
表示这个vector
存储的元素类型是int
(整数)。
2. m(128, 0)
:
- 这是
vector
的构造函数,用于初始化vector
。 - 括号中的两个参数分别是:
128
:表示vector
的初始大小为 128,即m
会包含 128 个元素。0
:表示vector
中每个元素的初始值为 0。
3. 整体含义:
vector<int> m(128, 0);
定义了一个名为m
的vector
,它包含 128 个整数元素,每个元素的初始值都是 0。- 等价于:
vector<int> m; // 定义一个空的 vector m.resize(128); // 将 vector 的大小调整为 128 for (int i = 0; i < 128; i++) { m[i] = 0; // 将每个元素初始化为 0 }
4. 在代码中的作用:
- 在这段代码中,
m
是一个大小为 128 的数组,用于记录每个字符最后一次出现的位置。 - 为什么大小是 128?
- 因为 ASCII 字符的范围是 0 到 127,总共有 128 个可能的字符。
- 通过
m[s[j]]
,可以根据字符的 ASCII 值快速访问对应的位置。
5. 示例:
假设 s = "abcabcbb"
,m
的初始状态为:
m = [0, 0, 0, ..., 0] // 128 个 0
当遍历字符串时:
- 遇到字符
'a'
(ASCII 值为 97),m[97]
会被更新为j + 1
(即当前字符的位置 + 1)。 - 遇到字符
'b'
(ASCII 值为 98),m[98]
会被更新为j + 1
。 - 以此类推。
总结:
vector<int> m(128, 0);
定义了一个大小为 128 的整数数组,初始值为 0。- 它的作用是记录每个字符最后一次出现的位置,从而帮助计算最长无重复字符子串的长度。