题目要求

Given a list, rotate the list to the right by k places, where k is non-negative.

For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.

其实这题的描述有些不妥当,确切的说是将最右侧的节点依次移到最左侧作为头结点,一直移动到右侧第k个节点后结束。
还是以1->2->3->4->5->NULL为例
k=1 结果为:5->1->2->3->4->NULL
k=2 结果为:4->5->1->2->3->NULL
k=3 结果为:3->4->5->1->2->NULL
k=4 结果为:2->3->4->5->1->NULL
k=5 结果为:1->2->3->4->5->NULL
k=6 结果为:5->1->2->3->4->NULL

换句话说 当k的值超过了list的长度len的时候,移动k次等价于移动k%len次

思路一:计算出list长度

即通过一次遍历,找到列表的末节点同时,计算出列表的长度。根据列表的长度,计算k%len,也就是最短等价移动次数。之后利用双指针,保证头指针和尾指针之间的距离始终为k,从而找到右边第k个节点。

    public ListNode rotateRight2(ListNode head, int k) {
        if(k==0 || head==null)
            return head;
        
        //get list length and last node
        ListNode last = head;
        int len = 1;
        while(last.next != null){
            last = last.next;
            len++;
        }
        
        
        k = k%len;
        if(k==0)
            return head;
        ListNode start = new ListNode(0);
        start.next = head;
        int count = len-k;
        while(count > 0){
            start = start.next;
            count--;
        }
        
        last.next = head;
        head = start.next;
        start.next = null;
        
        return head;
           
    }

思路二:简单优化

其实在某些情况下,k的值并不一定比数组的长度大。这时候还计算数组的长度的话,反而降低了性能。这个时候,可以将遍历的过程和头指针的移动结合起来。如果头指针移动到结尾而k并不是等于0,则可以得知k大于列表长度,同时这个过程还可以得出列表的长度。如果k等于0时,头指针未移动到末尾,则可以继续头指针和尾指针的同时移动,知道头指针到达数组的最后一个元素。
代码如下:

    public ListNode rotateRight(ListNode head, int k) {
        if(head == null){
            return null;
        }
        ListNode firstPointer = head;
        int length = 0;
        while(firstPointer!= null && k > 0){
            k--;
            firstPointer = firstPointer.next;
            length++;
        }
        if(k == 0){
            if(firstPointer == null){
                return head;
            }
            ListNode secondPointer = head;
            while(firstPointer != null && firstPointer.next!=null){
                secondPointer = secondPointer.next;
                firstPointer = firstPointer.next;
            }
            firstPointer.next = head;
            ListNode result = secondPointer.next;
            secondPointer.next = null;
            return result;
        }else{
            return rotateRight(head, k%length);
        } 
    }

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行