-
题目
给定一个单链表的头节点head,实现一个调整单链表的函数,使得每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点。
例如:
链表:1->2->3->4->5->6->7->8->null,k=3
调整后:3->2->1->6->5->4->7->8->null
-
分析
-
方法一:使用栈结构,原链表遍历每个元素压入栈,一旦栈的大小等于k,则依次出栈,并且要使之后逆序后的子串连接上遍历到当前位置的节点,如果最后入栈的子串长度不够k,则不需要出栈,也不用调整。
如图:
- 方法二:不使用栈结构,直接在原表中直接调整
每次遍历到第k个元素时,直接进行调整。
-
代码
public Node reverseKNode2(Node head, int K) { if (K < 2) //如果k小于2则无需调整直接返回 return head; Node cur = head; Node pre = null; Node start = null; Node next = null; int count = 1; while (cur != null) { next = cur.next; if (count == K) { //pre==null意味着是第一次进行逆序,以1,2,3,4,5为例, //第一次的时候start等于1,head等于3,这就是新的head //后面pre就是 start = pre == null ? head : pre.next; head = pre == null ? cur : head; resign2(pre, start, cur, next); } count++; cur = next; } return head; } /** * * @param left 将要逆序链表的前一个节点,也就是上段代码的pre * @param start 将要逆序链表的开始节点,就是pre.next * @param end 将要逆序链表的最后一个节点,就是cur * @param right 将要逆序链表的后面的节点 */ public void resign2(Node left, Node start, Node end, Node right) { Node pre = start; Node cur = start.next; Node next = null; /* * 经典的链表逆序算法 */ while (cur != right) { next = cur.next; cur.next = pre; pre = cur; cur = next; } if (left != null) { left.next = end; } start.next = end; }
-
参考资料
-
《程序员面试代码指南》 左程云