面试题: k个一组翻转单链表

题目地址

链表中的节点每k个一组翻转

注意点:

  • 本题考频很高!!!

  • 题目要求空间复杂度为 O ( 1 ) O(1) O(1), 因此无法使用递归

  • 本题可以借鉴翻转单链表一题,只是翻转单链表不需要引入辅助的头结点,为什么本题需要引入单独的辅助的头结点,下文会讲解。

面试题: k个一组翻转单链表_第1张图片

对于上面注意点的第三条,要封装的函数如下:

注意下面的函数是左闭右开即只翻转绿色的部分:
面试题: k个一组翻转单链表_第2张图片

//翻转一段链表(左闭右开)
//翻转从start到end之间的链表
    public ListNode ReverseList(ListNode start, ListNode end) {
        //使用非递归进行求解, 本题不需要进行引入辅助头结点
        ListNode pre = null;
        ListNode cur = start;
        ListNode nxt = start;
        while(cur!=end) {
            nxt = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }

上面的写法如果按照如下调用:其也可以充当翻转单链表的解法

ReverseList(head, null);

本题思路:

将每k个一组的翻转过程进行封装成一个单独的函数,函数的参数为开始结点和结束结点:ListNode start, ListNode end, 函数返回翻转后的新的起始节点,注意我们要保存下来每一组翻转后的新的结束结点(也就是每组未反转前的开始结点)让其指向下一组翻转后的新的开始结点。这也是为什么引入辅助头结点的原因,因为要考虑第一组的情况,需要让辅助的头结点指向第一组翻转后的新的开始结点。

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        ListNode cur = head;
        int cnt = 0;
        ListNode start = head;
        ListNode dummy = new ListNode(-1);
        ListNode pre_start = dummy;
        while(cur!=null) {
        	//找到本组的第k+1个结点赋值为cur
            while(cnt<k && cur!=null) {
                cur = cur.next;
                cnt++;
            }
            if (cnt==k) {//当while循环结束时,当前组正好有k个结点则翻转
                ListNode new_node = ReverseList(start, cur);
                pre_start.next = new_node;
                pre_start = start;
                start = cur;
                cnt = 0;
            } else {//当while循环结束时,当前组不足k个结点则不翻转,此时cur也肯定指向null
                pre_start.next = start;
            }

        }
        return dummy.next;
    }
    
    //辅助函数,翻转从start到end之间的链表
    public ListNode ReverseList(ListNode start, ListNode end) {
        //使用非递归进行求解, 本题不需要进行引入辅助头结点
        ListNode pre = null;
        ListNode cur = start;
        ListNode nxt = start;
        while(cur!=end) {
            nxt = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
}

你可能感兴趣的:(数据结构与算法)