将给出的链表中的节点每k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
要求空间复杂度O(1)
例如:
给定的链表是1->2->3->4->5
对于 k=2, 你应该返回 2->1->4->3->5
对于 k=3, 你应该返回 3->2->1->4->5
解答:利用栈结构的解法
1.如果k的值小于2,不用进行任何调整,因为k<1没有意义,k=1,代表一个节点为1组进行逆序,原链表没有进行任何变化。
2.从左到右遍历链表,如果栈的大小不等于看,就将节点不断压入栈中
3.当栈的大小第一次到达k时,说明第一次凑齐了k个节点进行逆序,从栈中依次弹出这些节点,并根据弹出的顺序重新连接,这一组逆序完成后,需要记录一下新的头部,同时第一组的最后一个节点(原来是头节点)应该连接下一个节点
例如:链表1->2-->3->4->5->6->7->8->null,k=3.第一组节点进入栈,从栈顶到栈底依次为3,2,1.逆序重连为3->2->1->......,然后节点1去连接节点4,链表变为3->2->1->4->5-->6->7-->8->null,之后从节点4不断处理k个节点为一组的后续情况,也就是步骤4,并且需要记录节点3,因为链表的头部已经改变,整个过程结束后需要返回这个新的头节点,记为newHead.
4.步骤3之后,当栈的大小每次到达k时,说明又凑齐了一组应该进行逆序的节点,从栈中依次弹出这些节点,并根据弹出的顺序重新连接。这一组逆序完成之后,该组的第一个节点(原来是该组最后一个节点)应该被上一组的最后一个节点连接上,这一组的最后一个节点(原来是该组第一个节点)应该连接下一个节点。然后继续去凑下一组,直到链表都被遍历完。
例如:链表3->2->1->4->5->6->7->8->null,k=3,第一组已处理完。第二组从栈顶到栈底依次为6,5,4.逆序重连之后为6->5->4,然后节点66应该被节点1连接,节点4应该连接节点7,链表变为3->2->1->6->5->4->7->8->null.然后继续从节点7往下遍历。
5.最后应该返回newHead,作为新的头节点。
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode reverseKGroup (ListNode head, int k) {
// write code here
if(k < 2) return head;
Stack<ListNode> stack = new Stack<ListNode>();
ListNode newHead =head;
ListNode cur = head;
ListNode pre = null;
ListNode next = null;
while(cur != null){
next = cur.next;
stack.push(cur);
if(stack.size() == k){
pre = resin1(stack,pre,next);
newHead = newHead == head ? cur :newHead;
}
cur = next;
}
return newHead;
}
public ListNode resin1(Stack<ListNode> stack,ListNode left,ListNode right){
ListNode cur = stack.pop();
if(left != null){
left.next = cur;
}
ListNode next = null;
while(!stack.isEmpty()){
next = stack.pop();
cur.next = next;
cur = next;
}
cur.next = right;
return cur;
}
}
但是,循环着做着同样的事,我们可以用一种方法来实现,是什么呢?当然是递归!
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if(head == null || head.next == null){
return head;
}
int count = 0;
ListNode curr = head;
while(count != k && curr != null){
curr = curr.next;
count++;
}
if(count == k){
curr = reverseKGroup(curr,k); //上一次翻转后的头节点
while(count -- > 0){ //翻转
ListNode tmp = head.next;
head.next = curr;
curr = head;
head = tmp;
}
head = curr;
}
return head;
}
}