2. Two Pointer
Template
Two pointer types:
• 对撞型 (2 sum 类 和 partition 类)
• 前向型 (窗口类, 快慢类)
• 两个数组,两个指针 (并行)
“对撞型”或“相会型”
//Two sum
if (A[left] + A[right] > sum)
right--;
do something
else if (A[left] + A[right] < sum)
left++;
do something
else
do something
left++ or right--
// 灌水类型题目思路
if (A[left] > A[right])
right--
else if (A[left] < A[right])
left++
else
left++ or right--
//Partition类模板
public int partition(int[] nums, int l, int r) {
// 初始化左右指针和pivot
int left = l, right = r;
int pivot = nums[left];
// 进行 partition
while (left < right) {
while (left < right && nums[right] >= pivot) {
right--;
}
nums[left] = nums[right];
while (left < right && nums[left] <= pivot) {
left++;
}
nums[right] == nums[left];
}
// 返还pivot点到数组里
nums[left] = pivot;
return left;
}
//Quick sort to call the partition function
public void quickSort(int[] nums, int l, int r) {
if (l < r) {
int pivotIndex = partition(nums, l, r);
quickSort(nums, l, pivotIndex - 1);
quickSort(nums, pivotIndex + 1, r);
}
}
// Partition 的另外一个模板
public void swap(int[] nums, int x, int y) {
int tmp = nums[x];
nums[x] = nums[y];
nums[y] = tmp;
}
public int partition(int[] nums, int left, int right) {
Random rand = new Random();
int pivotIndex = rand.nextInt((right - left) + 1) + left;
// Init pivot
int pivotValue = nums[pivotIndex];
swap(nums, pivotIndex, right);
// First index that nums[firstIndex] > pivotValue
int firstIndex = left;
for (int i = left; i <= right - 1; i++) {
if (nums[i] < pivotValue) {
swap(nums, firstIndex, i);
firstIndex++;
}
}
// Recover pivot to array
swap(nums, right, firstIndex);
return firstIndex;
}
快慢型
ListNode fast, slow;
fast = head;
slow = head;
while (fast!=null || fast.next!=null) {
fast = fast.next.next;
slow = slow.next;
}
Typical problems
NSum problems
//Two sum on an ordered array
//Find an index pair from an ordered array that the sum of them equal to target,
// return {-1, -1} if doesn't exist
public int[] twoSum(int[] numbers, int target) {
if (numbers == null || numbers.length == 0) {
return new int[] { -1, -1};
}
int left = 0, right = numbers.length - 1;
while (left < right) {
int sum = numbers[left] + numbers[right];
if (sum == target) {
return new int[] {left + 1, right + 1};
} else if (sum < target) {
left++;
} else {
right--;
}
}
return new int[] {-1,-1};
}
//Three sum on an array that might contains duplicates
// Find all the triples that adds up to zero
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}
Arrays.sort(nums);//注意,看数据集是否被sort了
for (int i = 0; i < nums.length; i++) {
if (i > 0 && nums[i] == nums[i - 1]) { //去重
continue;
}
int target = -nums[i];
int left = i + 1, right = nums.length - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum < target) {
left++;
} else if (sum > target) {
right--;
} else {
//注意
result.add(Arrays.asList(new Integer[]{nums[i], nums[left], nums[right]}));
while (left < right && nums[left] == nums[left+1]) { //左去重
left++;
}
while (left < right && nums[right] == nums[right-1]) {//右去重
right--;
}
//注意别忘记
left++;
right--;
}
}
}
return result;
}
Last updated