双指针

快慢指针:

慢指针用于保存性质,快指针用于探路。[0, 慢指针] 均满足性质

27.移除元素

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置
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
public int removeElement(int[] nums, int val) {
// brutal force:
int count = nums.length;
for (int i = 0; i < count; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < count; j++) {
nums[j - 1] = nums[j];
}
i -= 1;
count--;
}
}
return count;
// fast-slow pointers:
// 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
// 慢指针:指向更新 新数组下标的位置
int fast = 0, slow = 0;
while (fast < nums.length) {
while (fast < nums.length && nums[fast] == val) {
fast++;
}
if (fast == nums.length) break;
nums[slow] = nums[fast];
fast++;
slow++;
}
return slow;
}

相向双指针

977.有序数组的平方

由于满足性质:如果想要非递减顺序那么数组平方后的最大值一定在两侧并向中间收敛,因此相向双指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private int[] twoPointers(int[] nums) {
int[] res = new int[nums.length];
int k = nums.length - 1;
int left = 0, right = nums.length - 1;
while (left <= right) {
if (Math.abs(nums[left]) > Math.abs(nums[right])){
res[k--] = nums[left] * nums[left];
left++;
} else {
res[k--] = nums[right] * nums[right];
right--;
}
}
return res;
}

滑动窗口

框架:

1
2
3
4
5
6
for (int i = 0; i < n; i++) {
// 滑动窗口框架:
// 1. 入
// 2. 出
// 3. 记录答案
}

209.长度最小的子数组

窗口内满足题目要求的性质,不断更新并在过程中寻找最小值。

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
private int whileLoopVersionSlidingWindow(int target, int[] nums) {
int left = 0, right = 0;
int sum = nums[0];
int res = Integer.MAX_VALUE;
while (left <= right) {
if (sum < target) {
right++;
if (right < nums.length) {
sum += nums[right];
} else break;
} else {
res = Math.min(res, right - left + 1);
if (left + 1 < nums.length) {
sum -= nums[left];
left++;
}
else break;
}
}
return res == Integer.MAX_VALUE ? 0 : res;
}

private int forLoopVersionSlidingWindow(int[] nums, int s) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= s) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}