LeetCode-rotateRight

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个node,从那开始到结尾和之前那部分对调,那个例子就是,4->5拿前面来,1->2->3拿后面去。

几个特殊:

k是可以大于整个list的长度的,所以这时要对k对len取模

如果取模之后得0,相当于不用rotate,直接返回

思路(3种方法):

1、首先分析,涉及到一块链表,就要使用faster/slower双指针,,还涉及到链表的换位,那么要注意块链表的前驱节点的指向---->那么引出要构建一个新的head节点(下面还有种方法),new 一个ListNode;

    需要注意的是:双指针节点的位置。

public class RotateList {
    private class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }

     public ListNode rotateRight(ListNode head, int k) {
            if (head == null || head.next == null) {
                return head;
            }
            int len = 0;
            ListNode countlen = head;
            while (countlen != null) {
                len++;
                countlen = countlen.next;
            }
                        
            ListNode a = new ListNode(-1);
            a.next = head;
            head = a;
            
            ListNode r, p, q;
            r = head;
            p = r.next;
            q = r.next;
                        
            k = k % len;
        if(k == 0)      return head.next;
        
       for(int i= 1;i<k;i++){
               q= q.next;
           }
           
           while (q.next != null) {
                    q = q.next;
                    p = p.next;
                    r = r.next;

            }
            r.next = null;
            q.next = head.next;
            head.next = p;
            return head.next;
        }

 

2、处理完特殊情况后,就用熟悉的faster/slower双指针解决就好(看到这种linkedlist,倒着数数的,就条件反射了)

先对faster设步长为n,然后faster和slower再一起走,知道faster.next==null,说明slower指向要倒着数的开始点的前一个位置。

所以slow.next就是要返回的newhead,保存一下。

然后把faster.next接到head上,slower.next存为null,作队尾。

这样就把list给rotate了。

这里要注意,一个链表是用head来表示其在内存中的位置,因此,只要返回一个head,就可以找到该链表!因此,我们可以令链表的任意node为newhead,使尾节点的next为head(原来的),然后返回newhead,这就是链表常用思路

 public ListNode rotateRight(ListNode head, int k) {
        if(head==null||head.next==null)
            return head;
        k=k%length(head);
        if(k==0)
            return head;
        ListNode fast = head;
        ListNode slow = head;
        while(k-->0)
            fast=fast.next;

        while(fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        ListNode newHead=slow.next;         //这里重置一个head
        slow.next=null;
        ListNode cur=newHead;
        while(cur.next!=null)
            cur=cur.next;
        cur.next=head;
        return newHead;
    }

    public int length(ListNode head){
        int res=0;
        while(head!=null){
            res++;
            head=head.next;
        }
        return res;
    }

3、还有一种就是把整个list连起来,变成环,找到切分点断开就行。(循环链表来做。)

public ListNode rotateRight(ListNode head, int k) {
    
    if(head == null || head.next == null) return head;

    // Get length
    int len = 1;
    ListNode tail = head;
    while(tail.next != null) {
        tail = tail.next;
        len++;
    }

    // Go to position k distance to tail
    k = k % len;
    if(k == 0) return head;
    ListNode newTail = head;
    for(int i = 0; i < len - k - 1; i++) {
        newTail = newTail.next;
    }

    // Join two parts
    ListNode newHead = newTail.next;
    newTail.next = null;
    tail.next = head;

    return newHead;
}

 

posted @ 2016-01-12 21:11  wangb021  阅读(646)  评论(0编辑  收藏  举报