一天一道算法题(3)---将单链表的每k个节点之间逆序

  • 题目

给定一个单链表的头节点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;
    }
  • 参考资料

  1. 《程序员面试代码指南》 左程云

posted @ 2017-04-01 17:27  杨同不爱吃洋葱  阅读(1014)  评论(0编辑  收藏  举报