《剑指offer》——两个链表的第一个公共结点

60 篇文章 3 订阅

更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~

T:

题目描述
输入两个链表,找出它们的第一个公共结点。

  • 最基本的方法,遍历:

code:

	class ListNode {
	    int val;
	    ListNode next = null;
	
	    ListNode(int val) {
	        this.val = val;
	    }
	}
	
	/**
	 * T: 两个链表的第一个公共结点
	 * 
	 * 题目描述 
	 * 输入两个链表,找出它们的第一个公共结点。
	 * 
	 * date: 2015.11.16  16:18
	 * @author SSS
	 *
	 */
	public class Solution {
	
		/**
		 * 本方法的思想简单:就是逐个遍历,大循环套小循环,最终返回第一个公共节点
		 * 如果不存在公共节点,就返回null
		 * @param pHead1
		 * @param pHead2
		 * @return
		 */
		public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
			//两个链表任意一个为null,都返回null
			if (pHead1 == null || pHead2 == null) {
				return null;
			}
			
			 while (pHead1 != null) {
				 ListNode tempNode = pHead2;
				while (tempNode != null) {
					if (pHead1 == tempNode) {
						return pHead1;
					}
					tempNode = tempNode.next;
				}
				pHead1 = pHead1.next;
			}
			 
			 return null;
	    }
	}
  • 效率较高的方法:

sss

code:

	/**
	 * 题解的另一种方式,效率更高,O(n)
	 * 
	 * date: 2015.11.16  19:16
	 * @author SSS
	 *
	 */
	public class Solution1 {
	
		public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
			
			if (pHead1 == null || pHead2 == null) {
				return null;
			}
			
			 Integer firstLength = 0;
			 Integer secondLength = 0;
			 
			 ListNode tempNode = pHead1;
			 // 得到链表pHead1的长度
			 while (tempNode != null) {
				tempNode = tempNode.next;
				firstLength ++;
			}
			 tempNode = pHead2;
			 // 得到链表pHead2的长度
			 while (tempNode != null) {
				tempNode = tempNode.next;
				secondLength ++;
			}
			 
			 // 较长的那个链表先前进k步,其中k为两个链表长度的差值
			 Integer contrast = 0;
			 ListNode tempNode1 = pHead1;
			 ListNode tempNode2 = pHead2;
			 if (firstLength > secondLength) {
				contrast = firstLength - secondLength;
				while (contrast > 0) {
					tempNode1 = tempNode1.next;
					contrast --;
				}
			} else if (firstLength < secondLength) {
				contrast = secondLength - firstLength;
				while (contrast > 0) {
					tempNode2 = tempNode2.next;
					contrast --;
				}
			}
			 
			 // 两个链表的指针同时往后走
			 while (tempNode1 != null) {
				if (tempNode1 == tempNode2) {
					return tempNode1;
				}
				tempNode1 = tempNode1.next;
				tempNode2 = tempNode2.next;
			}
			 // 如果能到这一步,说明第一个链表已经到尾部,即到了null,
			 // 而能达到这一位置,只有一种情况,两个链表没有公共链表
			 return tempNode1;
	    }
	}
  • 当然,既然java已经都封装了那么多好的特性,为什么舍弃不用呢?

用hashMap或者hashSet都可解决此问题,但是其时间复杂度为多少,由于目前不知道hashMap中一些函数的执行效率和时间复杂度,比如public boolean containsValue(object value) 函数,其时间复杂度应该是O(n),抑或难道是O(1)?

code:

	import java.util.HashMap;
	
	/**
	 * 利用hashMap解决
	 * 
	 * date: 2015.11.16  21:25
	 * @author SSS
	 *
	 */
	public class Solution2 {
	
		/**
		 * 将第一个链表的所有元素都放在hashMap当中,然后对第二个链表进行遍历,看其在map当中是否存在
		 * @param pHead1
		 * @param pHead2
		 * @return
		 */
		public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
			if (pHead1 == null || pHead2 == null) {
				return null;
			}
			
			 HashMap<Integer, ListNode> nodeSet = new HashMap<Integer, ListNode>();
			 int k = 0;
			 
			 while (pHead1 != null) {
				 nodeSet.put(k++, pHead1);
				 pHead1 = pHead1.next;
			 }
			 
			 while (pHead2 != null) {
				if (nodeSet.containsValue(pHead2)) {
					return pHead2;
				}
				pHead2 = pHead2.next;
			 }
			 
			 
			 return pHead2;
	    }
	}

更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值