• 每日一题 为了工作 2020 0330 第二十八题


    /**
    * 问题:有环链表相交问题
    * 如何判断两个有环链表是否相交, 相交则返回第一个相交节点, 不相交则返回 null。
    *
    * 两个链表各自的第一个入环节点, 假设链表1的第一个入环节点记为 loop1,链表 2的第一个
    * 入环节点记为 loop2。
    *
    * 1.如果loop1 == loop2 ,我们只要考虑链表 1从头开始到 loop1这一段与链表 2从头
    * 开始到 loop2这一段, 在哪里第一次相交即可, 而不用考虑进环该怎么处理, 这就与单链表
    * 相交问题类似, 只不过单链表是把 null作为一个链表的终点, 而这里是把 loop1(loop2)
    * 作为链表的终点。但是判断的主要过程是相同的。
    *
    * 2.如果 loop1 != loop2,让链表 1从loop1出发, 因为loop1和之后的所有节点都在环
    * 上, 所以将来一定能回到loop1。如果回到 loop1之前并没有遇到 loop2,说明两个链表 不
    * 相交, 直接返回 null; 如果回到 loop1之前遇到了 loop2,说明两个链表相交。因为 loop1
    * 和 loop2都在两条链表上,只不过 loop1是离链表1较近的节点,loop2是离链表2较近的节点。
    * 所以, 此时返回loop1或loop2都可以。
    * @author 雪瞳
    *
    */

    *代码

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

      

    public class LoopNode {
    	
    	Node current1 = null;
    	Node current2 = null;
    	public Node loopNode(Node head1,Node head2,Node loop1,Node loop2){
    		int len1 = 0;
    		int len2 = 0;
    		if(loop1 == loop2){
    			current1 = head1;
    			while(current1!=loop1){
    				len1++;
    				current1=current1.next;
    			}
    			current2 = head2;
    			while(current2!=loop2){
    				len2++;
    				current2=current2.next;
    			}
    			if(len1>len2){
    				int pre = len1-len2;
    				int flag = 0;
    				current1 = head1;
    				current2 = head2;
    				while(current1!=current2){
    					flag++;
    					if(flag == pre){
    						current1=current1.next;
    						current2=current2.next;
    					}
    					current1=current1.next;
    				}
    				return current1;
    			}else if(len2>len1){
    				int pre = len2-len1;
    				int flag = 0;
    				current1 = head1;
    				current2 = head2;
    				while(current1!=current2){
    					flag++;
    					if(flag == pre){
    						current1=current1.next;
    						current2=current2.next;
    					}
    					current2=current2.next;
    				}
    				return current2;
    			}else{
    				return head1;
    			}
    		}
    		int loop = 0;
    		if(loop1 != loop2){
    			current1 = loop1.next;
    			current2 = loop2;
    			while(current1!=loop1){
    				if(current1 == current2){
    					loop =1;
    				}
    				current1=current1.next;
    			}
    		}
    		if(loop==0){
    			return null;
    		}else{
    			return loop1;
    		}		
    	}
    }
    

      

    import java.util.Random;
    import java.util.Scanner;
    
    
    public class TestLoopNode {
    
    	private int overTip = 0;
    	
    	
    	public static void main(String[] args) {
    		TestLoopNode test = new TestLoopNode();
    		LoopNode loop = new LoopNode();
    		Scanner sc = new Scanner(System.in);
    		Node result = null;
    		int length1;
    		System.out.println("请输入环链表长度:...");
    		length1 = sc.nextInt();
    		int length2;
    		System.out.println("请输入环链表长度:...");
    		length2 = sc.nextInt();
    		sc.close();
    		
    		Node head1;
    		Node head2;
    		head1=test.getCircleNodeList(length1);
    		System.out.println("链表初始状态信息:...");
    		test.showByTip(head1);
    		
    		head2=test.getCircleNodeList(length2);
    		System.out.println("链表初始状态信息:...");
    		test.showByTip(head2);
    		
    		//result = loop.loopNode(head1, head2, head1.next, head2.next);
    		//test.showResult(result);
    		//构造相交链表
    		Node current1 =head1.next;
    		while(current1.next!=head1){
    			current1=current1.next;
    		}
    		Node current2 =head2.next;
    		while(current2.next!=head2){
    			current2=current2.next;
    		}
    		current1.next=head2;
    		current2.next=head1;
    		
    		test.setOverTip(10);
    		test.showByTip(current1);
    	}
    	public int getOverTip() {
    		return overTip;
    	}
    	public void setOverTip(int overTip) {
    		this.overTip = overTip;
    	}
    	public void showResult(Node head){
    		if(head!=null){
    			System.out.println("环形链表相交,节点的值是:"+head.value);
    		}else{
    			System.out.println("环形链表不想交");
    		}
    	}
    	public void showByTip(Node head) {
    		Node current = null;
    		int cricleStopTip = 0;
    		System.out.println("链表内的元素顺序显示如下:...");
    		current=head;
    		while(current!=null) {
    			System.out.print(current.value+"	");
    			cricleStopTip ++;
    			current=current.next;
    			if(cricleStopTip/overTip==2){
    				System.out.println();
    				return;
    			}
    		}
    		System.out.println("");
    	}
    	
    	public Node getCircleNodeList(int listLength) {
    		overTip = listLength;
    		Random rand = new Random();
    		Node nodeList[]= new Node[listLength];
    		for(int i=0;i<listLength;i++) {
    			nodeList[i]= new Node(rand.nextInt(10)); 
    		}
    		for(int i=0;i<listLength-1;i++) {
    			nodeList[i].next=nodeList[i+1];
    		}
    		nodeList[listLength-1].next=nodeList[0];
    		return nodeList[0];
    	}
    }
    

      

  • 相关阅读:
    [ Openstack ] Openstack-Mitaka 高可用之 环境初始化
    [ Openstack ] OpenStack-Mitaka 高可用之 概述
    Swift
    Swift
    报错
    归并排序
    堆排序
    插入排序
    早睡早起身体好
    用于查询的日期类型转换帮助类
  • 原文地址:https://www.cnblogs.com/walxt/p/12597857.html
Copyright © 2020-2023  润新知