每日一题 为了工作 2020 0320 第十八题

/**
* 问题:反转部分单向链表
* 给定一个单向链表的头节点head,以及两个整数from和to,在单向链表上把第form个节点到第to个节点这一部分进行反转。
* 例如:
* 1->2->3->4->5->null, from=2, to=4
* 调整结果为: 1->4->3->2->5->null
* 再如:
* 1->2->3->null, from=1, to=3
* 调整结果为: 3->2->1->null
*
* 要求:
* 1.如果链表长度为 N, 时间复杂度要求为O(N), 额外空间复杂度要求为0(1)。
* 2.如果不满足 1<=from<=to<=N, 则不用调整。
* 分析:
* 本题有可能存在换头的问题, 比如题目的第二个例子,所以函数应该返回调整后的新
* 头节点, 整个处理过程如下:
*
* 1. 先判断是否满足1<=from<=to<=N, 如果不满足,则直接返回原来的头节点。
*
* 2. 找到第 from-1个节点fPre和第 to+1个节点tPos。fPre即是要反转部分的前一个节
* 点, tPos是反转部分的后一个节点。把反转的部分先反转,然后正确地连接 fPre和 tPos。
* 例如: 1->2->3->4>-null, 假设 fPre为节点 1, tPos为节点 4,要反转部分为2->3。
* 先反转成3->2, 然后 fPre连向节点 3, 节点 2连向 tPos,就变成了1->3->2->4->null。
*
* 3. 如果 fPre为 null, 说明反转部分是包含头节点的, 则返回新的头节点,也就是没反转之前反
* 转部分的最后一个节点, 也是反转之后反转部分的第一个节点; 如果 fPre不为 null,则直接
* 返回原头节点即可。
*
*
* @author 雪瞳
*
*/

*代码

public class Node<T> {
	public T value;
	public Node next;
	public Node(T data){
		this.value=data;
	}
}

  

public class ReversePartNode {

	//链表长度
	private int nodeLength = 0;
	//反转前一节点
	private Node prefixNode = null;
	//反转后一节点
	private Node suffixNode = null;
	//反转开始节点
	private Node startNode = null;
	//反转结束节点
	//private Node overNode = null;
	//指针节点
	private Node currentNode = null;
	private Node currentNextNode =null;
	
	public Node reversePart(Node head,int from,int to) {
		currentNode =head;
		while(currentNode!=null) {
			nodeLength++;
			//判断当前节点是否是前置节点或者是后置节点
			prefixNode = (nodeLength==from-1)?currentNode:prefixNode;
			suffixNode = (nodeLength==to+1)?currentNode:suffixNode;
			currentNode = currentNode.next;
		}
		//判断是否符合反转要求
		if(from<1 || to>nodeLength || to<from) {
			return head;
		}
		//开始反转
		//是否需要调整头节点
		startNode = (prefixNode==null)?head:prefixNode.next;
		currentNode = startNode.next;
		
		startNode.next = suffixNode;
		
		while(currentNode!=suffixNode) {
			currentNextNode = currentNode.next;
			currentNode.next = startNode;
			startNode = currentNode;
			currentNode=currentNextNode;
		}
		if(prefixNode!=null) {
			//连接节点
			prefixNode.next = startNode;
			return head;
		}else {
			return startNode;
		}
	}		
}

  

import java.util.Random;
import java.util.Scanner;

public class TestReversePartNode {
	public static void main(String[] args) {
		ReversePartNode reverse = new ReversePartNode();
		TestReversePartNode test = new TestReversePartNode();	
		//获取初始信息
		Random rand = new Random();	
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入链表长度");
		int K = sc.nextInt();
		System.out.println("请输入开始节点位置");
		int from = sc.nextInt();
		System.out.println("请输入结束节点位置");
		int to = sc.nextInt();
		//随机生成链表
		Node nodes[]=new Node[K];
		for(int i=0;i<nodes.length;i++) {
			nodes[i]=new Node(rand.nextInt(20)+1);
		}
		for(int i =0;i<nodes.length-1;i++) {
			nodes[i].next=nodes[i+1];
		}
		Node head = nodes[0];
		//test
		test.showNode(head);
		Node reverseNode = reverse.reversePart(head, from, to);
		test.showNode(reverseNode);
		
	}
	public void showNode(Node head) {
		System.out.println("链表内的元素如下所示...");
		while(head != null) {
			System.out.print(head.value+"\t");
			head = head.next;
		}
		System.out.println();
	}
}

  

*运行结果

 

猜你喜欢

转载自www.cnblogs.com/walxt/p/12530968.html
今日推荐