以下题目解法不是最优,有很简洁的算法。
3. 无重复字符的最长子串
吉比特面试时遇到的原题,思考思路用了一点时间,最慌的就是这段时间。然后用笔模拟了一遍双指针的过程,后面就只要分阶段实现思路就行了。
这里用的set集合,看题解用map会简单很多。
几个技巧:拆分为右指针滑动和左指针滑动,再循环下去。写代码先考虑最普通的情况,之后再考虑一些特殊情况,这里就需要有一个普通的测试用例。最后循环写好再考虑退出条件。其中用到while (true) ,和一些局部变量。
public static void main(String[] args) {
String s = "abcabcdeabc";
System.out.println(new Main().finds(s));
}
int i = 0;
int j = 0;
Set<Character> set = new HashSet<>();
int maxj;
int maxi;
int maxSize = 0;
String finds(String s) {
while (true) {
addIntoSet(s);//直到j已经被包含了
if (isStop1) {
break;
}
removeSet(s);//移动i直到是s[i]==s[j],移除后可以继续移动j,注意set
}
return s.substring(maxi, maxj);
}
private void removeSet(String s) {
char c = s.charAt(j);
while (true) {
char c1 = s.charAt(i);
if (c != c1) {
i++;
set.remove(c1);
continue;
} else {
set.remove(c1);
i++;
return;
}
}
}
boolean isStop1 = false;
private void addIntoSet(String s) {
while (true) {
if (j >= s.length()) {
isStop1 = true;
return;
}
char e = s.charAt(j);
if (set.contains(e)) {
return;
}
set.add(e);
j++;
if (set.size() > maxSize) {
maxSize = set.size();
maxi = i;
maxj = j;
}
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length()==0) return 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0;
int left = 0;
for(int i = 0; i < s.length(); i ++){
if(map.containsKey(s.charAt(i))){
left = Math.max(left,map.get(s.charAt(i)) + 1);
}
map.put(s.charAt(i),i);
max = Math.max(max,i-left+1);
}
return max;
}
}
- 最大子序和
这滑动窗口是有技巧帮助做到快速一遍过的。技巧在于拆分循环为先往右滑动,再调整左指针,然后依次循环。
public int maxSubArray(int[] nums) {
while (true) {
addnum(nums);
if (stop) {
return res;
}
i = j + 1;
j = i;
window = 0;
}
}
int res = Integer.MIN_VALUE;
boolean stop = false;
private void addnum(int[] nums) {
while (true) {
if (j >= nums.length) {
stop = true;
return;
}
window += nums[j];
if (window > res) {
res = window;
}
if (window <= 0) {
break;
}
j++;
}
}
int window = 0;
int i = 0;
int j = 0;