一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
题目描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
思路
这道题目对于一开始没有好的方案,可以使用暴力解法来完成,通过循环遍历就可以完成。
由于最长子串是连续的,通过滑动窗口的思路,可以一次遍历完成该题目,通过定义start、end两个指针来进行范围的筛选。
start、end区间为不重复的字符区间,定义一个 map 数据结构存储 (k, v),其中 key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复。
代码
public static void main(String[] args) {
String s = "sfsfsfsfs222";
int i = lengthOfLongestSubstring(s);
System.out.println(i);
}
private static int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
//定义hashmap用来记录
Map<Character, Integer> map = new HashMap<>(s.length());
//定义循环开始遍历
for (int end = 0, start = 0; end < n; end++) {
//得到本次循环的值,用来进行判断
char alpha = s.charAt(end);
//判断在map中是否包含与当前值一样的值,如果包含,则start需要赋值为新值,进行窗口右移
if (map.containsKey(alpha)) {
//赋值,窗口右移
start = Math.max(map.get(alpha), start);
}
//每次都计算ans长度
ans = Math.max(ans, end - start + 1);
//将当前值存入map,
map.put(s.charAt(end), end + 1);
System.out.println(end);
}
return ans;
}
总结
由于最长子串是连续的,通过使用滑动窗口,设定好了start、end,并使用map进行存储之后。在遍历的过程中,不过更新start、end的值确定区间,该区间为不重复子串的长度。明确好了这个观点之后,很快就能做好了