25. Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked 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

Solution1:recursive遞歸 寫法

從起始每k個作為一段,實現reverse當前段,并遞歸完成下一段的reverse。
Time Complexity: O(N) Space Complexity: O(k) 遞歸緩存

Solution2_a:iterative 寫法: 依次reverse

依次reverse: 1 -> 2 -> 3 -> 4
1 <- 2 -> 3 -> 4 再 1 <- 2 -< 3 -> 4 再 1 <- 2 <- 3 <- 4
本題中將每一段(k個) 內部依次reverse( 普通prev寫法),重新連接首尾后,繼續下一段
Time Complexity: O(N) Space Complexity: O(1)

Solution2_b:iterative 寫法: (后部)插入法reverse

1 -> 2 -> 3 -> 4
2 -> 3 -> 4 -> 1 再 3 -> 4 -> 2 -> 1 再 4 -> 3 -> 2 -> 1


屏幕快照 2017-09-11 下午9.23.22.png

本題中將每一段(k個) 內部依次插入法reverse,重新連接首尾后,繼續下一段
Time Complexity: O(N) Space Complexity: O(1)

Solution2_c:Iterative (前部)插入法reverse ?

1 -> 2 -> 3 -> 4
2 -> 1 -> 3 -> 4 再 3 -> 2 -> 1 -> 4 再 4 -> 3 -> 2 -> 1

Solution1 Code:

class Solution1 {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode curr = head;
        int count = 0;
        while (curr != null && count != k) { // find the k+1 node
            curr = curr.next;
            count++;
        }
        if (count == k) { // if k+1 node is found
            curr = reverseKGroup(curr, k); // reverse next section
            
            //reverse this section
            while (count-- > 0) { // reverse current k-group: 
                ListNode tmp = head.next; // save head.next
                head.next = curr; // (main) head.next = prev_head (except for the first time) 
                curr = head; // curr as prev_head
                head = tmp; // head to original next
            }
            head = curr;
        }
        return head;
    }
}

Solution2_a Code:

class Solution2_a {
    /**
     * Reverse a link list between begin and end exclusively
     * an example:
     * a linked list:
     * 0->1->2->3->4->5->6
     * |           |   
     * begin       end
     * after call begin = reverse(begin, end)
     * 
     * 0->3->2->1->4->5->6
     *          |  |
     *      begin end
     * @return the reversed list's 'begin' node, which is the precedence of node end
    */

    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode begin;
        if (head == null || head.next == null || k == 1)
            return head;
        ListNode dummyhead = new ListNode(0);
        dummyhead.next = head;
        begin = dummyhead;
        int i=0;
        while (head != null){
            i++;
            if (i % k == 0){
                begin = reverse(begin, head.next);
                head = begin.next;
            } else {
                head = head.next;
            }
        }
        return dummyhead.next;
    
    }

    public ListNode reverse(ListNode begin, ListNode end) {
        ListNode curr = begin.next;
        ListNode next, first;
        ListNode prev = begin;
        first = curr;
        while (curr != end){
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        begin.next = prev;
        first.next = curr;
        return first;
    }
}

Solution2_b Code:

lass Solution2_b {
    public ListNode reverseKGroup(ListNode head, int k) {
        if (head==null||head.next==null||k<2) return head;

        ListNode dummy = new ListNode(0);
        dummy.next = head;
        
        ListNode tail = dummy, prev = dummy,temp;
        int count;
        while(true) {
            count = k;
            while(count > 0 && tail != null){
                count--;
                tail = tail.next;
            } 
            if(tail == null) break;//Has reached the end
            
            head = prev.next;//for next cycle
            // prev-->temp-->...--->....--->tail-->....
            // Delete @temp and insert to the next position of @tail
            // prev-->...-->...-->tail-->head-->...
            // Assign @temp to the next node of @prev
            // prev-->temp-->...-->tail-->...-->...
            // Keep doing until @tail is the next node of @prev
            while(prev.next != tail){
                temp = prev.next;//Assign
                prev.next = temp.next;//Delete
                
                temp.next = tail.next;
                tail.next = temp;//Insert
            }
            tail = head;
            prev = head;
            
        }
        return dummy.next;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容