双指针
双指针,顾名思义,是一种使用两个指针相互配合来求解问题的方法。
例1:排序数组中两个数组之和
/**
* 排序数组两数之和
* 双指针
*
* @return
*/
@Test
public void test0331212() {
int[] arr = new int[]{3, 2, 4};
int target = 6;
//要进行排序
Arrays.sort(arr);
int j = 0, k = arr.length - 1;
//循环条件:两数之和不等于target
while (arr[j] + arr[k] != target && k > j) {
//移动指针
if (arr[j] + arr[k] > target) {
k--;
} else {
j++;
}
}
System.out.println(Arrays.toString(new int[]{j, k}));
}
例二:数组中和为零的三个数
/**
* 数组中和为0的三个数字
*/
@Test
public void test0331228() {
List<List<Integer>> result = new LinkedList<>();
int[] arr = new int[]{-1, 0, 1, 2, -1, -4};
Arrays.sort(arr);
int i = 0;
while (i < arr.length - 2) {
//在剩余的数组中查找两数之和为arr[i]的
int j = i + 1, k = arr.length - 1;
while (j < k) {
if (arr[i] * (-1) == arr[j] + arr[k]) {
result.add(Arrays.asList(arr[i], arr[j], arr[k]));
int temp = arr[j];
//去重
while (temp == arr[j] && j < k) {
j++;
}
} else if (arr[i] * (-1) > arr[j] + arr[k]) {
j++;
} else {
k--;
}
}
//这里也需要去重
int temp = arr[i];
while (i < arr.length && temp == arr[i]) {
i++;
}
}
System.out.println(result);
}
例三:和大于等于k的最短子数组
/**
* 和大于或等于k的最短子数组
*/
@Test
public void test0331419() {
int[] arr = new int[]{5, 1, 4, 3};
int target = 7, min_length = Integer.MAX_VALUE, j = 0, k = 0, sum = 0;
while (k < arr.length) {
sum += arr[k];
while (sum >= target && j <= k) {
min_length = Math.min(min_length, k - j + 1);
sum -= arr[j++];
}
k++;
}
min_length = min_length == Integer.MAX_VALUE ? 0 : min_length;
System.out.println(min_length);
}
例四:乘积小于k的连续子数组数
/**
* 乘积小于K的连续子数组的个数
*/
@Test
public void test0331431() {
int[] arr = new int[]{10, 5, 2, 6};
int target = 100, count = 0, j = 0, k = 0, product = 1;
while (k < arr.length) {
product *= arr[k];
while (product >= target && j <= k) {
product /= arr[j++];
}
count += j <= k ? k - j + 1 : 0;
k++;
}
System.out.println(count);
}