题意及思路
题意:大致是最尾节点(tail)移动到头节点,移动k次。
思路:@方法一(我起初的思路);先遍历一遍链表,得到其长度,用len对k取模(目的是想减少不必要的移动操作,比如一个链表长为3,k为4,其实只需要移动4%3次)。然后就是将尾节点移动到头节点的操作,具体操作见代码。
@方法二:基本上无异,有区别的是这个思路是将倒数k(k已经处理过)个数据一块移到头部去,具体实现见代码,另附上思维图
差异点:需要注意,第一个思路,一个一个移动需要增加虚拟节点(我习惯称为top节点),第二个思路则不需要用到。第二个代码的first、second是为了找到倒数第k+1个节点,然后将后面k个节点全部移到头部。这叫做双指针法,找倒数第k个节点。
代码1
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode rotateRight(ListNode head, int k) { if(head==null) return head; ListNode p = head,q,top = new ListNode(-1); top.next = head; int len = 0; while(p!=null) {len++; p=p.next;} k %= len; while(k-->0){ p = top; //找到尾节点前面一个位置 while(p.next.next!=null) {p=p.next;} q = p.next; p.next = q.next; q.next = top.next; top.next = q; } return top.next; } }
代码二
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode rotateRight(ListNode head, int k) { if(head==null) return head; ListNode first=head ,second=head; int len = 0; for(ListNode p=head;p!=null;p=p.next) len++; k %= len; //先让first移动k次 while(k-->0) first = first.next; //first、second同时移动 while(first.next!=null) { first=first.next; second=second.next; } first.next = head; head = second.next; second.next = null; return head; } }