Wednesday, October 16, 2013

Reverse Nodes in k-Group

Q:
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
A: 
 -----------  recursively----each time, detach the first k nodes , and reverse -----------
public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode header = new ListNode(0);
        helper(header,head,k);
        return header.next;
    }
    private void helper(ListNode tail, ListNode head, int k){
        if(head == null)
            return;
        ListNode runner = head;
        for(int i =0;i<k-1;i++){// run k-1 steps
            runner = runner.next;
            if(runner == null){
                tail.next = head;
                return;
            }
        }
        ListNode nextHead = runner.next;
        runner.next = null;
        // reverse from head to runner
        runner = head;
        while(runner != null){
            ListNode tmp = runner;
            runner = runner.next;
            tmp.next = tail.next;
            tail.next = tmp;
        }
        helper(head, nextHead, k);
    }
}


Mistakes:
1:在用for 循环,找到 第fastRunner的时候,因为最后运行的是
fastRunner = fastRunner.next;
所以,  在最有一个for的时候,  有可能就把fastRunner给搞成null了,
因此,要继续 test 是否为空

----------------------------第二遍-----------思路同上--------只是,不swap,而是直接加入另一个list, 加入的时候, 加到原本的tail之后而已。-------------

         不到k个的时候,更改了next值之后,却忘了break 最外边的while循环。

public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
     ListNode newHeader = new ListNode(0);
     ListNode tail = newHeader;
     ListNode oldHeader = new ListNode(0);
     oldHeader.next = head;
     while(oldHeader.next != null){
         // test whether we have k values in old list
         ListNode runner = oldHeader;
         for(int i =0;i<k;i++){
             if(runner == null){
                 break;
             }else{
                 runner = runner.next;
             }
         }
         if(runner == null){
             tail.next = oldHeader.next;
             break;
         }else{ // we have k nodes in oldList
             for(int i=0;i<k;i++){
                 ListNode tmp = oldHeader.next; 
                 oldHeader.next = oldHeader.next.next; 
                 
                 tmp.next = tail.next;
                 tail.next = tmp;
             }
             // after inserting these k values, we move tail to the last node
             while(tail.next!= null){
                 tail = tail.next;
             }
         }
     }
     return newHeader.next;
     }
}


---------------4rd pass-----------------

public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        int n =0;
        ListNode runner = head;
        while(runner!=null){
            runner = runner.next;
            n++;
        }
        return helper(head,n,k);
    }
    private ListNode helper(ListNode head, int n, int k){
        ListNode header = new ListNode(0);
        if(n >= k){// reverse
            ListNode curHead = head;
            for(int i =0;i<k;i++){
                ListNode tmp = head;
                head = head.next;
                
                tmp.next = header.next;
                header.next = tmp;
            }
            curHead.next = helper(head,n-k,k);
            return header.next;
        }else{
            return head;
        }
    }
}
Note: even for the inner detached list, it is still a good idea to have a header on it.
Learned:

这一遍写的时候,一开始看错题目了。 艹    思路有点儿乱, 忘记记录curNode了

No comments:

Post a Comment