• 每日一题 为了工作 2020 0406 第三十五题


    /**
     * 
     * 问题:合并两个有序的单链表
     *     给定两个有序单链表的头节点 head1和head2, 请合并两个有序链表, 合并后的链表依然有序,
     *     并返回合并后链表的头节点。
     * 	       例如:
     *	   0->2->3->7->null
     *     1->3->5->7->9->null
     *     合并后的链表为: 0-> 1->2->3->3->5->7->7->9->null
     * 
     * 解答:
     * 1.如果两个链表中有一个为空,说明无须合并过程, 返回另一个链表的头节点即可。
     * 
     * 2.比较head1和 head2的值, 小的节点也是合并后链表的最小节点 这个节点无疑应该是合并链表的头
     * 节点,记为 head; 在之后的步骤里, 哪个链表的头节点的值更小, 另一个链表的所有节点都会依次插
     * 入到这个链表中。
     * 
     * 3.不妨设 head节点所在的链表为链表 1,另一个链表为链表 2。链表 1和链表 2都从头部开始一起遍历,
     * 比较每次遍历到的两个节点的值, 记为 cur1和cur2, 然后根据大小关系做出不同的调整,同时用一个
     * 变量pre表示上次比较时值较小的节点。
     * 
     * 例如, 链表1为 1->5->6->null , 
     * 	         链表 2为 2->3->7->null。
     * 	  
     * 	      cur1=1,cur2=2, pre=null。cur1小于cur2, 不做调整, 因为此时 cur1较小,所以令
     * 	  pre=cur1=1,然后继续遍历链表 1的下一个节点, 也就是节点5。
     * 	      cur1=5,cur2=2, pre=1。cur2小于cur1,让 pre的 next指针指向 cur2,cur2的next
     * 	    指针指向 cur1。这样,cur2便插入到链表 1中。因为此时 cur2较小,所以令 pre=cur2=2,然后继续
     *   遍历链表 2的下一个节点, 也就是节点 3。这一步完成后, 链表1变为 1->2->5->6->null,链表2变为3->7->null。
     *   	  cur1=5, cur2=3, pre=2。cur1=5,cur2=3, pre=2。此时又是cur2较小,与上一步调
     *   整类似, 这一步完成后, 链表1变为1->2->3->5->6->null,链表2为7->null。
     *   	  cur1=5, cur2=7, pre=3。cur1=5, cur2=7, pre=3。cur1小于cur2,不做调整,因
     *   为此时cur1较小, 所以令pre=cur1=5, 然后继续遍历链表1的下一个节点,也就是节 点6。
     *        cur1=6, cur2=7, pre=5。cur1小于cur2, 不做调整, 因为此时cur1较小,所以令pre=cur1=6,
     *   此时已经走到链表1的最后一个节点, 再往下就结束, 如果链表1或链表2有任何一个走到了结束, 就进入步骤4。
     * 
     * 4.如果链表 1先走完, 此时cur1=null, pre为链表 1的最后一个节点, 那么就把 pre的 next指针指向链表2
     * 当前的节点(即cur2), 表示把链表2没遍历到的有序部分直接拼接到最后, 调整结束。如果链表2先走完, 说明链
     * 表2的所有节点都已经插入到链表l中,调整结束。
     * 
     * 5. 返回合并后链表的头节点head。
     * 
     * @author 雪瞳
     *
     */
    

      

    public class Node {
    
    	public int value;
    	public Node next;
    	public Node(int data){
    		this.value=data;
    	}
    }
    

      

    public class MergeNode {
    
    	
    	public Node mergeNode(Node head1,Node head2){
    		
    		if(head1 == null || head2 == null){
    			return head1 == null?head2:head1;
    		}
    		Node head = head1.value<head2.value?head1:head2;
    		
    		// current 1 存储的是较小的元素
    		// current 2 存储的是较大的元素
    		Node current1 = head == head1 ? head1:head2;
    		Node current2 = head == head1 ? head2:head1;
    		// 存放当前current1和current2中最小的元素
    		Node preCurrent = null;
    		Node nextCurrent = null;
    		
    		while(current1 != null && current2 != null){
    			
    			if(current1.value <= current2.value){
    				// 1 < 2 继续遍历直到出现 2 < 1 的情况
    				preCurrent = current1;
    				current1 = current1.next;
    			}else{ 
    				// 1 > 2 将节点2的当前元素插入到 1 中
    				nextCurrent = current2.next;
    				preCurrent.next = current2;
    				current2.next = current1;
    				
    				preCurrent = current2;								
    				current2 = nextCurrent;
    			}
    			
    		}
    		preCurrent.next = current1==null?current2:current1;
    		
    		return head;
    	}
    }
    

      

    public class TestMergeNode {
    
    	public static void main(String[] args) {
    		
    		TestMergeNode test = new TestMergeNode();
    		MergeNode merge = new MergeNode();
    		
    		Node n1 = new Node(1);
    		Node n2 = new Node(2);
    		Node n3 = new Node(3);
    		Node n4 = new Node(4);
    		Node n5 = new Node(5);
    		Node n6 = new Node(6);
    		Node n7 = new Node(7);
    		Node n8 = new Node(8);
    		Node n9 = new Node(9);
    		
    		n1.next = n2;
    		n2.next = n3;
    		n3.next = n4;
    		n4.next = n5;
    		Node head1 = n1;
    		
    		
    		n6.next=n7;
    		n7.next=n8;
    		n8.next=n9;
    		Node head2 = n6;
    		
    		test.showNodeList(head1);
    		test.showNodeList(head2);
    		Node result = merge.mergeNode(head1, head2);
    		test.showNodeList(result);
    	}
    	/*获取链表
    	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+"	");
    			current=current.next;
    		}
    		System.out.println();
    	}
    }
    

      

  • 相关阅读:
    适配器模式
    代理模式
    单例模式
    构建者(建造者)模式
    js Math方法
    补零
    js中十进制与二进制、八进制、十六进制的互相转换
    js生成一个范围内随机数Math.random
    js不改变原数组的情况下取数值数组的最大值和最小值
    自己封装方法,功能跟数组的indexof一样
  • 原文地址:https://www.cnblogs.com/walxt/p/12641597.html
Copyright © 2020-2023  润新知