题意及思路

题意:大致是最尾节点(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;
    }
}