反轉鏈表hard-leetcode25

給你鏈表的頭節點 head ,每 k 個節點一組進行翻轉,請你返回修改後的鏈表。

k 是一個正整數,它的值小於或等於鏈表的長度。如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。

你不能只是單純的改變節點內部的值,而是需要實際進行節點交換

思路:

每k個節點翻轉一次,相當於確定左右邊界翻轉一次,既轉換成92題目


//leetcode submit region begin(Prohibit modification and deletion)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        if(head == null){
            return null;
        }

        if(k==1){
            return head;
        }

        ListNode dummy = new ListNode(-1);
        dummy.next = head;



        int n = -1;
        while(dummy != null){
            n++;
            dummy = dummy.next;
        }

        //System.out.println("n = " + n);

        ListNode dummy1 = new ListNode(-1);
        dummy1.next = head;
        int[] reverseArray = new int[n];
        int left ;
        int right ;
        for ( left = 1,right = left+k-1; right <= n; left=right+1,right = left+k-1) {
            //System.out.println("left = " + left);
            //System.out.println("right = " + right);
            //閉區間【1,2】
            dummy1 =reverseBetween(dummy1.next, left, right);

            //ListNode dummy3 = new ListNode(-1);
            //dummy3.next = dummy1;
            //while(dummy3!=null) {
            //    System.out.print(" dummy3.val: " + dummy3.val);
            //    dummy3 = dummy3.next;
            //}

        }

        return  dummy1.next;
    }
    public ListNode reverseBetween(ListNode head, int left, int right) {
        if (head == null || head.next == null || left == right) {
            return head;
        }


        //虛擬節點爲了避免頭節點爲空
        ListNode dummy = new ListNode(-1);
        dummy.next = head;

        //分別記錄要反轉的前節點和要反轉的第一個節點
        ListNode currDummy = dummy;
        ListNode prevDummy = null;

        ListNode prev = null;
        ListNode curr = null;

        for (int i = 0; i < left; i++) {
            prevDummy = currDummy;
            currDummy = currDummy.next;
        }
        curr = currDummy;

        //反轉範圍內的節點
        for (int i = left; i <= right && curr !=null; i++){
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }

        //拼接節點,反轉前的結點 拼反轉後的頭結點
        prevDummy.next = prev;
        //反轉後的最後一個節點拼接right後的那個節點
        currDummy.next = curr;


        return dummy;

    }

}
//leetcode submit region end(Prohibit modification and deletion)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章