双指针操作数组
数组的基本操作,在数组的循环中,不断的定位符合条件的子数组
- 两个指针left和right
- 固定一个移动另一个,始终保持left <= right
例题1:由一个字符串由点和字母(大写或小写字母)组成,将字符串依次分成点的集合和字母集合,将字符串反转,但是字母的顺序不变,如:
输入:"aFC...b..cfb.."
输出:"..cfb..b...aFC"
class Test{
public static String getString(String str) {
//将字符串全部反转
char[] chars = str.toCharArray();
reverseChars(chars ,0 ,chars.length-1);
//利用双指针将每个单词反转
int i = 0;
int j = 0;
while (j < chars.length) {
//找到第一个字符
while (i < chars.length && chars[i] == '.') {
i++;
}
j = i;
//找到末位置(由于前面i==j,第一次循环都成立,则j无论怎样都大于i)
while (j < chars.length && chars[j] != '.') {
j++;
}
reverseChars(chars ,i ,j-1);
i = j;
}
return new String(chars);
}
private static char[] reverseChars(char[] chars ,int i ,int j){
while (i < j) {
char temp = chars[i];
chars[i++] = chars[j];
chars[j--] = temp;
}
return chars;
}
}
滑动窗口
滑动窗口算法用于数组中的连续子元素问题,需要用到双指针操作数组。可以将循环嵌套的问题转化为单循环的问题,降低时间复杂度
- 需要两个指针left和right
- 通常需要一个指针固定,另一个指针不断累加
- 窗口可由right不断累加扩大
- 窗口也可由left不断累加减小
例题1:没有重复字符的子字符的最大长度:给一个字符串,获得没有重复字符的最长子字符的长度
class Test{
public int getInt(String s){
HashSet<Character> set = new HashSet<>();
int left = 0;
int right = 0;
int result = 0;
while (left < s.length() && right < s.length()) {
if (!set.contains(s.charAt(right))) {
set.add(s.charAt(right++));
result = Math.max(result ,right - left);
}else {
set.remove(s.charAt(left++));
}
}
return result;
}
}