方法一:好理解,但是需要遍历三次链表
/*** 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+1current = 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;}
}