给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc"
,所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke"
,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
1、将字符串分为两个集合,第一个集合是目前最长串,第二个集合是需要加入最长串的字符
每次从第二个集合拿一个字符串,判读是否第一个集合存在该字符串
开始 NULL S{abcabcbb}
{a} {bcabcbb} //加入第一个结合
{ab} {cabcbb}
{abc} {abcbb}
{bca} {bcbb} //重复了,需要调整第一个字符串
..... 直到第二个字符串为空
- public int lengthOfLongestSubstring(String s) {
- if(s==null || s.length()==0) return 0;
- int len = s.length();
- int left=0,right=0,max=1;
-
- for(int i=1;i
- boolean find = false;
- for(int j=left;j<=right;j++){
- if(s.charAt(j)==s.charAt(i)){
- left=j+1;
- right=i;
- find=true;
- if(right-left+1>max)
- max=right-left+1;
- break;
- }
- }
- if(find == false){
- right=i;
- if(right-left+1>max)
- max=right-left+1;
- }
-
- }
-
- return max;
- }
将for 循环替换为java 字符串函数
-
- public static int lengthOfLongestSubstring(String s) {
- if(s==null || s.length()==0) return 0;
- int len = s.length();
- int left=0,right=0,max=1;
-
- for(int i=1;i
-
- String src=s.subSequence(left,right+1).toString();
- int offset = src.indexOf(s.charAt(i));
-
- if(offset != -1){
- left+=offset+1;
- right=i;
- if(right-left+1>max)
- max=right-left+1;
- continue;
- }
-
-
- right = i;
- if (right - left + 1 > max)
- max = right - left + 1;
-
- }
-
- return max;
- }
方法一:滑动窗口
思路和算法
我们先用一个例子考虑如何在较优的时间复杂度内通过本题。
我们不妨以示例一中的字符串 abcabcbb\texttt{abcabcbb}abcabcbb 为例,找出从每一个字符开始的,不包含重复字符的最长子串,那么其中最长的那个字符串即为答案。对于示例一中的字符串,我们列举出这些结果,其中括号中表示选中的字符以及最长的字符串:
以 (a)bcabcbb\texttt{(a)bcabcbb}(a)bcabcbb 开始的最长字符串为 (abc)abcbb\texttt{(abc)abcbb}(abc)abcbb;
以 a(b)cabcbb\texttt{a(b)cabcbb}a(b)cabcbb 开始的最长字符串为 a(bca)bcbb\texttt{a(bca)bcbb}a(bca)bcbb;
以 ab(c)abcbb\texttt{ab(c)abcbb}ab(c)abcbb 开始的最长字符串为 ab(cab)cbb\texttt{ab(cab)cbb}ab(cab)cbb;
以 abc(a)bcbb\texttt{abc(a)bcbb}abc(a)bcbb 开始的最长字符串为 abc(abc)bb\texttt{abc(abc)bb}abc(abc)bb;
以 abca(b)cbb\texttt{abca(b)cbb}abca(b)cbb 开始的最长字符串为 abca(bc)bb\texttt{abca(bc)bb}abca(bc)bb;
以 abcab(c)bb\texttt{abcab(c)bb}abcab(c)bb 开始的最长字符串为 abcab(cb)b\texttt{abcab(cb)b}abcab(cb)b;
以 abcabc(b)b\texttt{abcabc(b)b}abcabc(b)b 开始的最长字符串为 abcabc(b)b\texttt{abcabc(b)b}abcabc(b)b;
以 abcabcb(b)\texttt{abcabcb(b)}abcabcb(b) 开始的最长字符串为 abcabcb(b)\texttt{abcabcb(b)}abcabcb(b)。
发现了什么?如果我们依次递增地枚举子串的起始位置,那么子串的结束位置也是递增的!这里的原因在于,假设我们选择字符串中的第 kkk 个字符作为起始位置,并且得到了不包含重复字符的最长子串的结束位置为 rkr_kr
k
。那么当我们选择第 k+1k+1k+1 个字符作为起始位置时,首先从 k+1k+1k+1 到 rkr_kr
k
的字符显然是不重复的,并且由于少了原本的第 kkk 个字符,我们可以尝试继续增大 rkr_kr
k
,直到右侧出现了重复字符为止。
这样一来,我们就可以使用「滑动窗口」来解决这个问题了:
我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的 rkr_kr
k
;
在每一步的操作中,我们会将左指针向右移动一格,表示 我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。我们记录下这个子串的长度;
在枚举结束后,我们找到的最长的子串的长度即为答案。
判断重复字符
在上面的流程中,我们还需要使用一种数据结构来判断 是否有重复的字符,常用的数据结构为哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)。在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。
至此,我们就完美解决了本题。
作者:力扣官方题解
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- class Solution {
- public int lengthOfLongestSubstring(String s) {
- // 哈希集合,记录每个字符是否出现过
- Set
occ = new HashSet(); - int n = s.length();
- // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
- int rk = -1, ans = 0;
- for (int i = 0; i < n; ++i) {
- if (i != 0) {
- // 左指针向右移动一格,移除一个字符
- occ.remove(s.charAt(i - 1));
- }
- while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
- // 不断地移动右指针
- occ.add(s.charAt(rk + 1));
- ++rk;
- }
- // 第 i 到 rk 个字符是一个极长的无重复字符子串
- ans = Math.max(ans, rk - i + 1);
- }
- return ans;
- }
- }
-
- 作者:力扣官方题解
- 链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/
- 来源:力扣(LeetCode)
- 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
-
相关阅读:
1024程序员节:庆祝编程的魅力
BI国产化,必须要弄懂的2个关键
解决VSCode中Debug和运行路径不一致的
中国第一口粮大国科技领域的超级阵营 国稻种芯百团计划行动
期望+拆贡献+充斥:CF1349D
基于HFSS的线阵综合分析
企业应用架构研究系列一:业务拆分
基于Java毕业设计二手手机回收平台系统源码+系统+mysql+lw文档+部署软件
Spring的三种依赖注入的方式
【Redis】SortedSet类型
-
原文地址:https://blog.csdn.net/lei7143/article/details/133186909