一、题目
给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是子串的长度,“pwke” 是一个子序列,不是子串。
提示:
- 0 <= s.length <= 5 * 104
- s 由英文字母、数字、符号和空格组成
二、题解
- 使用滑动窗格框选最终结果区间
- Hashset哈希集合用来标记是否出现过在字符,同时,contains()用来检验是其中是否含有某字符
- for循环遍历数组,每一个for过程都会有一个while用于窗格向右拓展,一旦进入下一个for循环就说明本次窗格已经到了最大,需要左侧删除一个字符
- 对于字符串,charAt(角标数)用来定位其中一个字符
- 起始时,滑动窗格指针要在 − 1 -1 −1处,表示窗格中一个字符也没有
三、代码
public int lengthOfLongestSubstring(String s) {
//哈希表,记录每个字符是否出现过
Set<Character> symbol = new HashSet<Character>();
int n = s.length();
int rk = -1, result = 0; // 左边界指针(起始),最终结果
for (int i = 0; i < n; i++) {
//滑动窗格左侧去除
if (i != 0) { //此处每一次for循环更新一次就说明下一个要读取的字符出现重复,滑动窗格左侧右移一个去重
symbol.remove(s.charAt(i - 1));
}
//滑动窗格右侧拓展
while (rk < n - 1 && !symbol.contains(s.charAt(rk + 1))) { //下一个字符还不在哈希集合里
symbol.add(s.charAt(rk + 1));
rk++;
}
result = Math.max(result, rk - i + 1);
}
return result;
}
四、结果
五、总结
HashSet
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
- HashSet 允许有 null 值。
- HashSet 是无序的,即不会记录插入的顺序。
add()
add() 方法将元素插入到指定位置的动态数组中。
add() 方法的语法为:
arraylist.add(int index,E element)
注:arraylist 是 ArrayList 类的一个对象。
参数说明:
- index(可选参数)- 表示元素所插入处的索引值
- element - 要插入的元素
如果 index 没有传入实际参数,元素将追加至数组的最末尾。
返回值:
- 如果成功插入元素,返回 true。
注意:如果 index 超出范围,则该 add() 方法抛出 IndexOutOfBoundsException 异常。
contains()
contains() 方法用于判断元素是否在动态数组中。
contains() 方法的语法为:
arraylist.contains(Object obj)
注:arraylist 是 ArrayList 类的一个对象。
参数说明:
- obj - 要检测的元素
返回值:
- 如果指定的元素存在于动态数组中,则返回 true。
- 如果指定的元素不存在于动态数组中,则返回 false。
Math.max()
max() 方法用于返回两个参数中的最大值。
语法
该方法有以下几种语法格式:
double max(double arg1, double arg2)
float max(float arg1, float arg2)
int max(int arg1, int arg2)
long max(long arg1, long arg2)
参数
- 该方法接受两个原生数据类型作为参数。
返回值
- 返回两个参数中的最大值。
六、说明
本文章仅用于记录个人做题记录
由于本人是个小菜鸡(实锤),题目解法并非最优,且解题过程中参考(抄袭)各大佬解题方法,望见谅。