Example 2:
Input: head = [7,9,6,6,7,8,3,0,9,5], k = 5
Output: [7,9,6,6,8,7,3,0,9,5]
给出一个单向链表,交换正向第k个 和 逆向第k个元素。
思路:
由于是单向链表,不能从最后一个节点逆着往回找第k个节点,
所以在正向找到第k个节点以后,用快慢指针,快指针就从第k个出发,慢指针从head出发,
当快指针到达最后一个节点时,慢指针就正好在从结尾开始往回数的第k个节点处。
当然,找第k个节点比较容易,麻烦的是指针交换,
尤其是下面两种情形处理还不一样,用n1表示第k个节点,n2表示倒数第k个节点
case 1: …-> n1 -> node -> … -> node-> n2 -> …
case 2: node -> … -> node -> n1 -> n2 -> … -> node
其中case2如果按case1的办法去交换指针,就会形成环。
既然这么麻烦,那就不交换指针了?题目中说是swapping the values,所以直接交换两个node的值吧。
思路打开,链表节点还是原来的节点,把值交换一下就行了。不要纠结于如何交换指针。
public ListNode swapNodes(ListNode head, int k) {
ListNode n1 = head;
ListNode n2 = head;
ListNode fast = head;
for(int i = 1; i < k; i++) {
fast = fast.next;
}
n2 = fast;
while(fast.next != null) {
fast = fast.next;
n1 = n1.next;
}
//swap value
int tmp = n1.val;
n1.val = n2.val;
n2.val = tmp;
return head;
}
版本2,不用快慢指针,直接3个指针一起走。
public ListNode swapNodes(ListNode head, int k) {
ListNode cur = head;
ListNode kth = head;
ListNode lastKth = head;
int cnt = 1;
while(cur.next != null) {
cur = cur.next;
if(cnt < k) kth = kth.next;
if(cnt >= k) lastKth = lastKth.next;
cnt ++;
}
int tmp = kth.val;
kth.val = lastKth.val;
lastKth.val = tmp;
return head;
}