每日一题 为了工作 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();
	}
}

  

*运行结果

 

 

posted @ 2020-04-01 13:19  雪瞳  阅读(145)  评论(0编辑  收藏  举报