算法思想一:栈

解题思路:

利用栈的先进后出规则实现链表的翻转
1、首先遍历链表k个结点入栈,若k大于链表的长度则直接返回链表不翻转
2、栈内结点出栈(翻转)
3、判断剩下的链表个数够不够k个(少于k个不需要反转,大于k个重复 1、2步骤)
4、将已翻转的部分与剩下的链表连接起来
图解:

代码展示:

Python版本
class Solution:
    def reverseKGroup(self , head , k ):
        # write code here
        # 用于链表头元素
        Phead = ListNode(None)
        p = Phead
        while True:
            count = k
            stack = []
            tmp = head
            # 进栈
            while count and tmp:
                stack.append(tmp)
                tmp = tmp.next
                count -= 1
            # 跳出上面循环,tmp是第k+1的元素
            # 如果循环结束,count不为0,则代表不足k个元素
            if count:
                p.next = head
                break
            # 对k个元素进行反转
            # 出栈
            while stack:
                p.next = stack.pop()
                p = p.next
            # 与剩下链表链接起来
            p.next = tmp
            head = tmp
        return Phead.next

复杂度分析

时间复杂度O(N):N表示链表的个数,最差情况下需要遍历所有的链表结点
空间复杂度O(K):辅助栈最多存储k个结点

算法思想二:递归

解题思路:

1、找到待翻转的k个节点(注意:若剩余数量小于 k 的话,则不需要反转,因此直接返回待翻转部分的头结点即可)。
2、对其进行翻转。并返回翻转后的头结点(注意:翻转为左闭又开区间,所以本***作的尾结点其实就是下一***作的头结点)。
3、对下一轮 k 个节点也进行翻转操作。
4、将上一轮翻转后的尾结点指向下一轮翻转后的头节点,即将每一轮翻转的k的节点连接起来。
图解:

代码展示:

JAVA版本
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 count = 0;
        // 找到待反转的第k个结点
        while (cur != null && count != k) {
            cur = cur.next;
            count++;
        }
        if (count == k) {
            // 递归
            cur = reverseKGroup(cur, k);
            // 反转列表
            while (count != 0) {
                count--;
                ListNode tmp = head.next;
                head.next = cur;
                cur = head;
                head = tmp;
            }
            // 拼接后续的链表
            head = cur;
        }
        return head;
    }
}

复杂度分析

时间复杂度O(N):N表示链表的个数,最差情况递归遍历所有结点
空间复杂度O(1):使用常数级变量空间