LeetCode(25)K个一组反转链表
一个体面人的刷题之旅
题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
题目分析
首先,这是一道链表反转题目,我们要对操作动作和数据结构的关联敏感,一看到翻转,就想到先进后出啊,这样就顺序反转了不嘛!一提到先进后出!!------栈!
解法一 利用栈
既然让我们每K个节点反转那么我们把原链表的每K个节点依次入栈,在把我们K个节点依次出栈,循环这样做,直到将所有的节点反转完成,(这里要考虑的是当剩余的节点小于K时,我们就不改变顺序了,所以这种情况是我们的一个分支)。
talk is cheap,show me the code!
所有的链表题我们都需要定义一个哑巴节点来指向我们的入参节点,这样我们在最后可以直接返回哑巴节点的next返回我们操作的链表头就可以了。(我开始的时候真的不懂为什么,后来做多了慢慢就懂了。所以大家加油,别放弃 不会可以 多做几遍,在不会 就在做,实在不行 锻炼身体 找阿姨去把)
ListNode dumy = new ListNode(0);
dumy.next = head;
然后,这里我们要定义一个current节点,通过这个节点我们可以做到不改变dumy指针的情况下,对head进行翻转。
ListNode current = dumy;
这里还需要定义个next节点,表示我们正在翻转的节点,这个节点从我们要翻转链表的头部开始。
ListNode next = dumy.next
初始化一个栈容器用来翻转链表
Stack<ListNode> context = new Stack<ListNode>();
接下来就是遍历节点,把它们放到栈里,然后提取翻转。
while(next != null){//循环终止条件,当操作节点是null,也就是遍历到了链表末尾了
//这里把节点放入栈,这里要满足的条件是节点不能未null,并且循环次数小于翻转的个数
for(int i =0; i < k && next!= null; i++){
context.push(next);//放入
next= next.next;//要翻转的节点,更新到下一个节点
}
//判断特殊情况,也就是放入栈中的节点数量小于k,说明我们遍历到最后了,剩余的节点不满足一次翻转的数量,我们直接返回dumy.next,终止操作就可以了。
if(context.size() != k) return dumy.next;
//出栈,翻转,
while(context.size()!= 0){
current.next = context.pop();
current = current.next;
}
//这里是将当前节点指向剩余未翻转节点,这样我们在如果剩余长度不满足k的情况下就可以直接返回了。
current.next = next;
}
整体流程就这样,第一次写,大家见谅。下面贴出全部代码:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dumy = new ListNode(0);
dumy.next = head;
ListNode current = dumy;
ListNode next = current.next;
Stack<ListNode> context = new Stack<ListNode>();
while(next != null){
for(int i= 0; i < k && next!=null; i++){
context.push(next);
next = next.next;
}
if(context.size() != k) return dumy.next;
while(context.size()!= 0){
current.next = context.pop();
current = current.next;
}
current.next = next;
}
return dumy.next;
}
}
大家考虑下,我们可不可以不用额外空间实现呢?
解法二
大家考虑下,我们可不可以不用额外空间实现呢?
待续。。。