Skip to content

Commit ef5cbb8

Browse files
committed
add new solutions
1 parent 612ddc5 commit ef5cbb8

3 files changed

+111
-0
lines changed
File renamed without changes.
File renamed without changes.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
题目:
3+
链接;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
4+
3. Longest Substring Without Repeating Characters
5+
Given a string, find the length of the longest substring without repeating characters.
6+
7+
Examples:
8+
9+
Given "abcabcbb", the answer is "abc", which the length is 3.
10+
11+
Given "bbbbb", the answer is "b", with the length of 1.
12+
13+
Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
14+
15+
*/
16+
17+
/*
18+
作者知乎链接:https://www.zhihu.com/people/bing-mo-43-95/activities
19+
20+
解析:
21+
此题统计的是最长不重复子串的长度,由于没有让输出最长子串,所以会简单一些。
22+
23+
第一种解法:枚举出所有的不重复子串,需要两层循环O(n^2),同时还需要剔除所有的重复子串,这里就很不不好实现了
24+
,既要时间 还需要空间,所以这种暴力列举的方法暂且放一放,想都不要想。
25+
26+
27+
*/
28+
29+
/*第二种解法:HashMap (最后一个案例超时)
30+
31+
解析:
32+
33+
找这种不重复的最长子串,要从第一个元素找,找到重复的为止,而且由于不确定性与随机性,
34+
找到一个不重复的子串以后,要从第二个位置找起,比如:abcdaeb 这个子串,先找到第一个不重复子串:abcd 之后,不能从d(3)之后找下一个
35+
而是要从b(1)开始,寻找下一个。
36+
从这里开始就有很多中实现方法了,我用的是一种HashMap方法来寻找不重复子串,代码见下面。
37+
38+
复杂度分析:有两层循环构成,总次数是n + n-1 + n-2+...+0 所以复杂度有O(n^2),这是一个不好的算法。
39+
40+
改进:问题出现在哪里呢?
41+
42+
*/
43+
class Solution {
44+
public int lengthOfLongestSubstring(String s) {
45+
//记录当前不重复元素的最大值
46+
int maxLen = 0;
47+
int i,j;
48+
//建立一个HashMap,用来记录当前最大子串
49+
Map<Character,Integer> charMap = new HashMap<Character,Integer>();
50+
51+
//逐一扫描元素,开始寻找
52+
for(i =0;i<s.length();i++) {
53+
//从当前元素的下一个寻找不重复的元素。
54+
charMap.put(s.charAt(i),i);
55+
for(j = i+1;j<s.length();j++) {
56+
//如果charMap中有这个元素,那么此次查找的以i为首的最大子列结束。
57+
if(charMap.containsKey(s.charAt(j))) {
58+
//更新最大长度
59+
maxLen=Math.max(maxLen,j-i);
60+
break;
61+
}
62+
else{
63+
charMap.put(s.charAt(j),j);
64+
}
65+
66+
}
67+
//完成一轮将当前最大子串清空,并重新更新最大长度。
68+
maxLen=Math.max(maxLen,j-i);
69+
charMap.clear();
70+
}
71+
72+
return maxLen;
73+
}
74+
}
75+
76+
/*第三种方法,改进第一种方法。
77+
第二种方法,为什么这么慢呢?因为原本已经添加进charMap里面的元素,在最后的时候clear了,然后有得重新添加。
78+
导致了重复计算。
79+
80+
这时候,我们不再删去全部,而是要将charMap里面的元素向右移动一位,(可以用删掉charMap第一位来得到),还有一个需要注意的就是,要确保加入新元素,不会造成重复,从而不断删除首个元素直到没有重复。
81+
82+
*/
83+
84+
class Solution {
85+
public int lengthOfLongestSubstring(String s) {
86+
//记录当前不重复元素的最大值
87+
int maxLen = 0;
88+
int i,j=0;//用j来表示,要删除元素的位置
89+
//建立一个HashMap,用来记录当前最大子串
90+
Map<Character,Integer> charMap = new HashMap<Character,Integer>();
91+
92+
//逐一扫描元素,开始寻找
93+
for(i =0;i<s.length();i++) {
94+
while(charMap.containsKey(s.charAt(i))) {
95+
//更新最大长度
96+
maxLen=Math.max(maxLen,charMap.size());
97+
//确保没有重复的元素才能加入新元素
98+
charMap.remove(s.charAt(j++));
99+
}
100+
101+
charMap.put(s.charAt(i),i);
102+
103+
104+
}
105+
//针对最后一个元素,重新更新最大长度。
106+
maxLen=Math.max(maxLen,charMap.size());
107+
108+
109+
return maxLen;
110+
}
111+
}

0 commit comments

Comments
 (0)