题目:
输入两个链表,找出它们的第一个公共节点。例如下面的两个链表:两个链表的头结点都是已知的,相交之后成为一个单链表,但是相交的位置未知,并且相交之前的结点数也是未知的,请设计算法找到两个链表的合并点
分析:
这道题就是找的第一个相同的元素我们可以用HashMap存储元素,优点判断元素存不存在的速度快,我们就可以遍历一条链表将他的元素全部存入HashMapp,然后我们在遍历另外一条链表判断HashMap 里面有没有该元素,下面直接看代码
代码:
节点类:
// 节点类
public class Node<T> {
// 数据域 存储数据
public T data;
// 指针域 下一个节点的引用
public Node<T> next;
public Node(T data) {
this.data = data;
}
}
链表:
package linked;
public class LinkedList<T> {
// 头节点
public Node<T> head;
// 链表长度
private int size;
// 构造方法
public LinkedList() {
head = new Node(null);
}
// 在链表头部添加节点
public void addToHeader(T data) {
// 创建新节点
Node<T> newNode = new Node(data);
// 将新节点添加到头节点的后面
newNode.next = head.next;
head.next = newNode;
// 链表长度加一
size++;
}
// 在链表中间添加节点
public void addToMiddle(T data) {
// 创建新节点
Node<T> newNode = new Node(data);
// 从头节点开始遍历
Node<T> temp = head;
int index = size / 2;
// 找到要插入位置的前一个节点
for (int i = 0; i < index; i++) {
temp = temp.next;
}
// 将新节点添加到要插入位置的前一个节点的后面
newNode.next = temp.next;
temp.next = newNode;
// 链表长度加一
size++;
}
// 在链表尾部添加节点
public void addToTail(T data) {
// 创建新节点
Node<T> newNode = new Node<>(data);
// 从头节点开始遍历
Node<T> temp = head;
// 找到最后一个节点
while (temp.next != null) {
temp = temp.next;
}
// 将新节点添加到最后一个节点的后面
temp.next = newNode;
// 链表长度加一
size++;
}
// 返回最后一个节点
public Node<T> getLast() {
// 从头节点开始遍历
Node<T> temp = head;
// 找到最后一个节点
while (temp.next != null) {
temp = temp.next;
}
return temp;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
// 从头节点开始遍历
Node<T> temp = head;
// 遍历链表
while (temp.next != null) {
// 将节点的数据域添加到字符串中
sb.append(temp.next.data);
sb.append(",");
// 将节点的指针域指向下一个节点
temp = temp.next;
}
// 删除最后一个逗号
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
}
方便构造条件
实现类:
package linked.question.silver;
import linked.LinkedList;
import linked.Node;
import java.util.HashSet;
import java.util.Set;
/**
* 两个链表的头结点都是已知的,相交之后成为一个单链表,但是相交的位置未知,
* 并且相交之前的结点数也是未知的,请设计算法找到两个链表的合并点。
*/
public class No1 {
public static void main(String[] args) {
LinkedList<String> A1 = new LinkedList<>();
A1.add("a1");
A1.add("a2");
LinkedList<String> B1 = new LinkedList<>();
B1.add("b1");
B1.add("b2");
B1.add("b3");
LinkedList<String> C1 = new LinkedList<>();
C1.add("c1");
C1.add("c2");
C1.add("c3");
A1.getLast().next = C1.head.next;
B1.getLast().next = C1.head.next;
System.out.println(findFirstCommonNodeBySet(A1.head.next, B1.head.next).data);
}
// 利用HashSet的特性,如果两个链表相交,那么相交之后的结点都是相同的
public static <T> Node<T> findFirstCommonNodeBySet(Node<T> A, Node<T> B) {
// 创建一个HashSet集合
Set<Node<T>> set = new HashSet<>();
// 遍历链表A,将结点添加到集合中
while (A != null){
set.add(A);
A = A.next;
}
// 遍历链表B,判断结点是否在集合中
while (B != null){
if (set.contains(B)){
return B;
}
B = B.next;
}
// 如果没有相交的结点,返回null
return null;
}
}
findFirstCommonNodeBySet 就是我们主要实现的逻辑,这里使用HashSet 避免又重复的元素
用俩个while 循环遍历链表,今天介绍就到这里咯