链表练习(一)— K个节点的组内逆序调整

可参考之前的单链表反转,实现K个节点的组内逆序调整
说明:
给定一个单链表的头部节点head,和一个正整数K,实现K个节点内的小组内部逆序,如果最后不够一组,就不进行调整。
例如:
a -> b -> c -> d -> e -> f -> g -> h k = 3
调整后:
c -> b -> a -> f -> e -> d -> g -> h

分析:

  1. 如果节点整体长度为2,不满足一次分组,则不需进行排序,直接返回之前head节点即可。
  2. 按K分组逆序后,每组新的end节点的next可以指向下一组逆序后的新head。
  3. 第一组排序后,新的head就是整个链表的head节点。

代码实现:
使用静态内部类创建一个Node类

 public static class Node {
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

获取每个组内的end节点

	//返回小组的最后一个
    //假设链表中节点为a -> b -> c -> d -> e -> f  k = 3
    //则,第一次返回c
    public static Node getKGroupEnd(Node start, int k) {
    //假设单链表中节点数为2,但是K为3,那么节点长度不满足K,
    //每次减减后,K还不为0,但是start.next会为null
        while (--k != 0 && start != null) {
            start = start.next;
        }
        return start;
    }

组内反转,并获取下一组的head节点

	// a -> b -> c ->d -> e -> f  k = 3
    // c -> b-> a -> d   并且将a 指向 d
    public static void reverse(Node start, Node end) {
        Node next = null;
        Node pre = null;
        Node cur = start;
        end = end.next;

        while (cur != end) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        start.next = end;
    }

最终,将两个代码进行整合,是链表可以实现整体组内逆序的功能

 public static Node reverseKGroup(Node head, int k) {
        Node start = head;
        Node end = getKGroupEnd(head, k);
        //说明此时链表长度不足K的长度,
        if (end == null) {
            return head;
        }
        //第一次获取到的end节点会作为反转后新的head节点返回
        head = end;
        reverse(start, end);
        //记录反转后的上一个end
        Node lastEnd = start;
        //如果上一个为null,说明链表长度刚好被K一次性分割
        while (lastEnd.next != null) {
            start = lastEnd.next;
            end = getKGroupEnd(start, k);

            if (end == null) {
                return head;
            }
            reverse(start, end);
            lastEnd.next = end;
            lastEnd = start;
        }
        return head;
    }

你可能感兴趣的:(算法,链表,java,算法)