算法基础之打印相交链表的公共节点

不考虑带环的情况... :evil:
这里面其实包含了两个问题:判断链表相交和找两个相交链表的第一个公共点。
思路:首先需要理解的是若两个链表相交,则[color=red]一定是呈Y型[/color]。所以我们分别遍历两个链表,找到最后一个节点,若它们相同,则一定相交。然后我们从后往前考虑,假设两个链表有n个公共节点,两个链表的长分别为l和m(设l>m),那么我们先让较长的链表遍历l-m个。两个链表剩余部分长度是相等的(m),则同步遍历比较,若相同,则输出。

import com.linkedlist.LinkedListReverse.Node;

/**
* 打印相交链表的公共节点
*
* @author aaron-han
*
*/
public class LinkedListCommonNodes {

public static void main(String[] args) {
Node a = new Node("NodeA");
Node b = new Node("NodeB");
Node c = new Node("NodeC");
Node d = new Node("NodeD");
Node e = new Node("NodeE");
Node f = new Node("NodeF");
Node g = new Node("NodeG");
Node h = new Node("NodeH");

// a->f->g->h
a.next = f;
f.next = g;
g.next = h;

// b->c->d->e->f->g->h
b.next = c;
c.next = d;
d.next = e;
e.next = f;
f.next = g;
g.next = h;

System.out.println(isIntersected(a, c));
printCommonNode(a, c);

}

// 判断是否相交
public static boolean isIntersected(Node a, Node b) {
Node headA = a;
Node headB = b;
while (headA.next != null) {
headA = headA.next;
}
while (headB.next != null) {
headB = headB.next;
}
if (headA == headB) {
return true;
}
return false;
}

// 打印公共节点
public static void printCommonNode(Node a, Node b) {
int lengthA = getListLength(a);
int lengthB = getListLength(b);

Node longerList = a;
Node shorterList = b;
int lengthDiff = lengthA - lengthB;

if (lengthDiff < 0) {
longerList = b;
shorterList = a;
lengthDiff = lengthB - lengthA;
}
// 使较长的链表先遍历lengthDiff个
for (int i = 0; i < lengthDiff; i++) {
longerList = longerList.next;
}
// 此时等长,同步遍历
while (longerList != null && shorterList != null) {
if (longerList == shorterList) {
System.out.println(longerList.name);
}
longerList = longerList.next;
shorterList = shorterList.next;
}
}

public static int getListLength(Node node) {
int length = 0;
if (node == null) {
return length;
}
while (node != null) {
node = node.next;
length++;
}
return length;
}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值