题目描述 & 链接
LintCode 228. 链表中点 - 同向双指针
LintCode 31. Partition Array - 相向双指针
LintCode 200. Longest Palindromic Substring - 背向双指针
具体思路
1. 同向双指针
同向双指针通常解题思路就是一个主指针,一个辅助指针,主指针每次循环中一般走一步,每一次循环中辅助指针不断向前扫描,典型同向双指针:
- 快慢针找某个位置
- KMP算法扫描的过程也类似同向双指针
- 归并排序
快慢针找中点代码如下
public class Solution {
/**
* @param head: the head of linked list.
* @return: a middle node of the linked list
*/
public ListNode middleNode(ListNode head) {
// write your code here
if(head==null || head.next==null) return head;
ListNode fast = head;
ListNode slow = head;
while(fast!=null) {
if(fast.next!=null && fast.next.next!=null) fast = fast.next.next;
else break;
slow = slow.next;
}
return slow;
}
}
归并排序 - 归并部分代码如下:
private int[] merge(int[] A, int st, int ed) {
// merge sort
if(st==ed) return new int[]{A[st]};
int mid = st + (ed-st>>1);
int[] left = merge(A, st, mid);
int[] right = merge(A, mid+1, ed);
// 同向双指针
int i = 0;
int i1 = 0;
int i2 = 0;
int n = left.length;
int m = right.length;
int[] res = new int[m+n];
while(i1<n && i2<m) {
if(left[i1]<=right[i2]) res[i++] = left[i1++];
else res[i++] = right[i2++];
}
while(i1<n) res[i++] = left[i1++];
while(i2<m) res[i++] = right[i2++];
return res;
}
2. 相向双指针
对向双指针通常解决的一些对称性问题如回文判断,快速排序中partition的步骤也是通过相向双指针进行位置互换。大体流程就是定义左右指针,两个指针根据某些条件不断逼近直到重合。
快排partition代码如下:
private void quickSort(int[] A, int st, int ed) {
if(st>=ed) return;
int l=st, r=ed;
int pivot = A[st+(ed-st>>1)];
while(l<=r) {
while(l<=r && A[l]<pivot) l++;
while(l<=r && A[r]>pivot) r--;
if(l<=r) {
int tmp = A[l];
A[l] = A[r];
A[r] = tmp;
l++; r--;
}
}
quickSort(A, st, r);
quickSort(A, l, ed);
}
3. 背向双指针
背向双指针通常解决一些特定位置附近满足条件的解,比如找最接近target的K个值;还有通过背向移动来寻找满足某些条件的最大长度解,如寻找最长回文子串。
private String twoPointers(String s, int l, int r) {
String res = "";
char[] arr = s.toCharArray();
int n = s.length();
while(l>=0 && r<n) {
if(arr[l]==arr[r]) {
if(l==r) res+=arr[l];
else res = arr[l] + res + arr[r];
l--; r++;
} else return res;
}
return res;
}