双指针专题
问题一 寻找中间节点
问题描述
已知一个链表,返回链表的中间节点,如果有两个中间节点,则返回第二个。详见leetcode
方法描述
设置两个指针fast,slow同时指向head,fast每次走两步,slow每次走一步,fast为空时,slow即为中间节点
代码实现
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast!=null&&fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
问题二 寻找倒数第K个节点
问题描述
已知一个链表,返回链表的倒数第K个节点(链表尾部是倒数第一个节点)
方法描述
设置两个指针fast,slow同时指向head,fast先走K步,然后fast和slow一起走,当fast为空时,slow即是倒数第K个节点。
代码实现
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
while(fast!=null&&k>0){
fast = fast.next;
k--;
}
while(fast!=null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
问题三 旋转链表
问题描述
已知一个链表,将这个链表的每一个节点向后移动K个位置。详见leetcode
方法描述
直接按照问题要求向后每一个节点向后移动K个位置是比较复杂的。仔细观察,每一个节点向后移动K步,可以直接将倒数第K个节点以及之后的节点直接拼接到链表头部。也可以通过链表反转来实现。双指针专题,就通过第一种方式吧。
代码实现
public ListNode rotateRight(ListNode head, int k) {
if(head==null|| k==0){
return head;
}
ListNode slow = head;
ListNode fast = head;
ListNode current = head;
int count = 0;
while(current!=null){
current= current.next;
count++;
}
count = k%count;
if(count==0){
return head;
}
while(fast!=null&&count>0){
fast = fast.next;
count--;
}
while(fast.next!=null){
slow = slow.next;
fast = fast.next;
}
current = slow.next;
slow.next = null;
fast.next = head;
return current;
}