方法一:好理解,但是需要遍历三次链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapNodes(ListNode head, int k) {
ListNode ahead = new ListNode(0,head);
ListNode current = ahead;
ListNode topK = new ListNode(0,null);
ListNode botK = new ListNode(0,null);
int count = 0;
//第一次遍历,找到正数第K个节点,然后用一个新的节点暂存信息,同时求得总节点个数
while(current.next!=null){
count++;
current = current.next;
if(count==k){
topK.val = current.val;
topK.next = current.next;
}
}
//count为总节点个数
//第二次遍历找到倒数第K个节点,然后用一个新的节点暂存信息
//正数是k,倒数换成正数就应该是链表的长度-k+1
current = ahead;
int increase = 0;
while(current.next!=null){
increase++;
current = current.next;
//找到倒数第K个节点,然后用一个新的节点暂存信息
if(increase ==(count+1-k)){
botK.val = current.val;
botK.next = current.next;
}
}
current = ahead;
int num = 0;
//第三次遍历,交换两个节点
while(current.next!=null){
num++;
current = current.next;
if(num==k){
current.val= botK.val;
//current.next=current.next;//仅仅是交换的节点的val值
}
if(num==(count+1-k)){
current.val=topK.val;
//current.next=current.next;
}
}
return ahead.next;
}
}
方法二,值遍历一次,但是要注意指针的挪动次数关系的理解
/*
*声明三个节点cur、first、last全部指向head节点
利用current从头结点开始遍历链表,
topK指针移动k - 1步后定位至该链表正数第k个节点,
设链表的节点个数为nums,当first指针指向第k个节点时,
此时链表还有nums - k个节点没有遍历。
因为链表的头节点到倒数第k个节点之间的节点个数刚好也是nums - k个,
所以当遍历到正数第k个节点后,
botK指针开始从head节点移动nums - k步后即指向了倒数第k个节点。
*/
class Solution {
public ListNode swapNodes(ListNode head, int k) {
ListNode current = head;
ListNode topK = head;
ListNode botK = head;
int count = 1;
while(current.next!=null){
if(count<k){
topK = topK.next;
}else{
botK = botK.next;
}
count++;
current = current.next;
}
//交换两个节点
int temp = topK.val;
topK.val = botK.val;
botK.val = temp;
return head;
}
}