反转链表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)

posted @ 2023-04-03 10:15  小傻孩丶儿  阅读(12)  评论(0编辑  收藏  举报