• 每日一题 为了工作 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+"	");
    			head = head.next;
    		}
    		System.out.println();
    	}
    }
    

      

    *运行结果

     

  • 相关阅读:
    0001_two_sum
    shell 命令
    先验概率,后验概率,似然函数,最大似然估计【待整理】
    numpy学习笔记
    python: __slots__ 解析 (待整理)
    ubuntu,win7双系统问题
    安装sogou输入法
    pytorch安装
    稀疏向量的一些内容
    extern c
  • 原文地址:https://www.cnblogs.com/walxt/p/12530968.html
Copyright © 2020-2023  润新知