-
Notifications
You must be signed in to change notification settings - Fork 21
/
Longest Substring Without Repeating Characters.java
executable file
·180 lines (151 loc) · 4.98 KB
/
Longest Substring Without Repeating Characters.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
M
1519971156
tags: Hash Table, Two Pointers, String
方法1:
Two Pointers
双指针: 从start开始遍历, 但是第一步是while loop来推进end; 直到推不动end, 然后start++
巧妙点: 因为end是外围variable, 在start的loop上, end不会重置;[star ~ end] 中间不需要重复计算.
最终可以O(n);
Previous verison of two pointers:
用两个pointer, head和i.
注意:head很可能被退回到很早的地方,比如abbbbbba,当遇到第二个a,head竟然变成了 head = 0+1 = 1.
当然这是不对的,所以head要确保一直增长,不回溯
方法2:
HashMap<Char, Integer>: <character, last occurance index>
一旦有重复, rest map.
没有重复时候, 不断map.put(), 然后求max值
问题: 每次reset map之后就开始从新从一个最早的index计算, 最坏情况是O(n^2):
'abcdef....xyza'
```
/*
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
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.
*/
/*
Thoughts:
two pointers
Find the end fisrt, then move the start.
O(n)
*/
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
boolean[] chars = new boolean[256]; // 256 ASCII code
int rst = 0;
int start = 0;
int end = 0;
while (start < s.length()) {
while (end < s.length() && !chars[s.charAt(end)]) {
chars[s.charAt(end)] = true;
rst = Math.max(rst, end - start + 1);
end++;
}
chars[s.charAt(start)] = false;
start++;
}
return rst;
}
}
/*
Thoughts:
1. Use hashmap<c, index> to mark indexes of chars.
2. When no duplicate, put in map, and compare Math.max(rst, map.size())
3. If duplicated c appears, should ignore all index before the fist c, and start fresh:
reset i = map.get(c); map = new HashMap<>(), clean up the hash.
Time:
O(n^2): when 'abcdefg.....xyza' happends
*/
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
HashMap<Character, Integer> map = new HashMap<>();
char[] arr = s.toCharArray();
int rst = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
if (map.containsKey(c)) {
i = map.get(c); // reset beginning
map = new HashMap<>();
} else {
map.put(c, i);
}
rst = Math.max(rst, map.size());
}
return rst == Integer.MIN_VALUE ? 0 : rst;
}
}
/*
LintCode
Given a string, find the length of the longest substring without repeating characters.
Example
For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3.
For "bbbbb" the longest substring is "b", with the length of 1.
Challenge
O(n) time
Tags Expand
String Two Pointers Hash Table
*/
/*
02.02.2016
Attempt2, Thoughts:
HashMap<Char,Integer> map
When char re-appear in map, 1. move head to repeating char's index + 1, 2. renew map with current index
Note: head could repeat in earlier index, so make sure head does not travel back
*/
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int head = 0;
int max = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (map.containsKey(c)) {
if (map.get(c) + 1 > head) {//make sure head does not travel back
head = map.get(c) + 1;
}
}
map.put(c, i);
String str = s.substring(head, i + 1);
max = Math.max(max, str.length());
}
return max;
}
}
/*
Attempt1, Thoughts:
Loop the string, HashSet to store the Character, count++, and use a max to store longest length.
Whenever a char exist in hashset, new hashset and count = 0, set i = 1st duplicate char, followed by i++, now start again.
*/
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int count = 0;
int max = 0;
for (int i = 0; i < s.length(); i++) {
if (!map.containsKey(s.charAt(i))) {
map.put(s.charAt(i), i);
count++;
} else {
i = map.get(s.charAt(i));
map = new HashMap<Character, Integer>();
count = 0;
}
max = Math.max(max, count);
}//end for
return max;
}
}
```