每日一题 为了工作 2020 0401 第三十题
------------恢复内容开始------------
/**
* 问题:将单链表的每 K个节点之间逆序
* 给定一个单链表的头节点 head, 实现一个调整单链表的函数, 使得每 K个节点之间逆序,
* 如果最后不够 K个节点一组, 则不调整最后几个节点。
*
* 例如:
* 链表: 1->2->3->4->5->6->7->8->null , K= 3。
* 调整后为: 3->2-> 1->6->5->4->7->8->null 。其中7、8 不调整, 因为不够一组。
*
* 利用栈结构的解法。
*
* 1. 从左到右遍历链表, 如果栈的大小不等于 K, 就将节点不断压入栈中。
*
* 2. 当栈的大小第一次到达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个节点为
* 一组的后续情况,也就是步骤 3, 并且需要记录节点 3, 因为链表的头部已经改变, 整个过程
* 结束后需要返回这个新的头节点, 记为newHead。
*
* 3. 步骤 2之后, 当栈的大小每次到达 K时, 说明又凑齐了一组应该进行逆序的节点,从栈中依次弹
* 出这些节点, 并根据弹出的顺序重新连接。这一组逆序完成后, 该组的第一个节点(原来是该组
* 最后一个节点)应该被上一组的最后一个节点连接上, 这一组的最后一个节点(原来是该组第一
* 个节点)应该连接下一个节点。然后继续去凑下一组, 直到链表都被遍历完。
*
* 例如: 链表 3->2-> 1->4->5->6->7->8->null, K = 3, 第一组已经处理完。第二
* 组从栈顶到栈底依次为 6, 5, 4。逆序重连之后为 6->5->4, 然后节点6应该被节点1连接,
* 节点4应该连接节点 7, 链表变为3->2->1->6->5->4->7->8 ->null。然后继续从节点
* 7往下遍历。
*
* 4. 最后应该返回 newHead, 作为链表新的头节点。
*
* @author 雪瞳
*
*/
*代码
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
import java.util.Stack;
public class ReverseNodeByK {
private Stack<Node> stack = null;
public Node reverseNodeByK(Node head , int k){
Node current = null;
Node currentNext= null;
Node newHead = null;
Node preCurrent = null;
if(k<2 || head == null){
return head;
}
stack = new Stack<>();
current = head;
while(current != null){
currentNext = current.next;
stack.push(current);
if(stack.size() == k){
preCurrent = popStackNode(stack, preCurrent, currentNext);
//第一次遍历将反转后的节点作为链表头节点
newHead = newHead==null?current:newHead;
}
current=currentNext;
}
return newHead;
}
public Node popStackNode(Stack<Node> stack, Node leftCurrent ,Node rightCurrent){
Node trans = stack.pop();
if(leftCurrent!=null){
leftCurrent.next=trans;
}
Node next = null;
while(!stack.isEmpty()){
next = stack.pop();
trans.next=next;
trans = next;
}
trans.next=rightCurrent;
//将尾结点返回
return trans;
}
}
import java.util.Random;
import java.util.Scanner;
public class TestReverseNodeByK {
public static void main(String[] args) {
TestReverseNodeByK test = new TestReverseNodeByK();
ReverseNodeByK reverse = new ReverseNodeByK();
Scanner sc = new Scanner(System.in);
System.out.println("输入链表长度");
int len=0;
len =sc.nextInt();
int k=0;
System.out.println("输入反转长度");
k=sc.nextInt();
Node node = test.getNodeList(len);
test.showNodeList(node);
Node result = reverse.reverseNodeByK(node, k);
test.showNodeList(result);
sc.close();
}
public Node getNodeList(int length){
Random rand = new Random();
Node nodeArray[]= new Node[length];
for(int i=0;i<length;i++){
nodeArray[i]=new Node(rand.nextInt(10));
}
for(int i=0;i<length-1;i++){
nodeArray[i].next = nodeArray[i+1];
}
return nodeArray[0];
}
public void showNodeList(Node head){
Node current = null;
current = head;
System.out.println("链表元素如下...");
while(current!=null){
System.out.print(current.value+"\t");
current=current.next;
}
System.out.println();
}
}
*运行结果