算法总结之 将单链表的每K个节点之间逆序
给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点
思路:
如果k的值小于2,不调整。k<1 没有意义,k==1代表1个节点为1组进行逆序,原链表不变。
介绍两种方法:
方法一 利用栈结构
1、从左到右便利链表,如果栈的大小不等于k,就将节点不断压入栈中
2、当栈大小第一次到达k,凑齐了k个节点进行逆序。然后弹出,并且连接。第一组逆序完成后,记录新的头,同时第一组最后一个(原头)连接下一个节点
package TT;
import java.util.Stack;
public class Test103 {
public class Node{
public int value;
public Node next;
public Node(int data){
this.value = data;
}
}
public Node reverseKNodes1(Node head, int k){
if(k<2){
return head;
}
Stack<Node> stack = new Stack<Node>();
Node newHead = head;
Node cur = head;
Node pre = null;
Node next = null;
while(cur!=null){
next = cur.next;
stack.push(cur);
if(stack.size()==k){
pre=resign1(stack, pre, next);
newHead = newHead==head ? cur : newHead;
}
cur = next;
}
return newHead;
}
public Node resign1(Stack<Node> stack, Node left, Node right){
Node cur = stack.pop();
if(left !=null){
left.next=cur;
}
Node next=null;
while(!stack.isEmpty()){
next = stack.pop();
cur.next=next;
cur=next;
}
cur.next=right;
return cur;
}
}
方法二、不需要栈结构,在原链表中直接调整
用变量记录每一组开始的第一个节点和最后一个节点。然后直接逆序调整,把这一组的节点都逆序。和方法一一样,同样需要注意第一组节点的特殊处理,以及之后的每个组在逆序重连之后,需要让该组的第一个节点(原来是最后一个节点)被之前的最后一个连上,将该组的最后一个节点连接下一个节点
package TT; public class Test104 { public class Node{ int value; public Node next; public Node(int data){ this.value = data; } } public Node reverseKNodea2(Node head, int k){ if(k<2){ return head; } Node cur = head; Node start=null; Node pre=null; Node next=null; int count=1; while(cur!=null){ next = cur.next; if(count==k){ start=pre==null?head:pre.next; head=pre==null?cur:head; resign2(pre,start,cur,next); pre=start; count=0; } count ++; cur=next; } return head; } public void resign2(Node left, Node start, Node end, Node right){ Node pre=start; Node cur=start.next; Node next=null; while(cur!=null){ next=cur.next; cur.next=pre; pre=cur; cur=next; } if(left!=null){ left.next=end; } start.next=right; } }