算法通关村第一关链表经典问题之两个链表第一个公共子节点笔记

题目:

输入两个链表,找出它们的第一个公共节点。例如下面的两个链表:两个链表的头结点都是已知的,相交之后成为一个单链表,但是相交的位置未知,并且相交之前的结点数也是未知的,请设计算法找到两个链表的合并点

 分析:

这道题就是找的第一个相同的元素我们可以用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 循环遍历链表,今天介绍就到这里咯

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值