LeetCode-160 相交链表(链表)

一、题目

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交:
在这里插入图片描述
题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

自定义评测:

评测系统 的输入如下(你设计的程序 不适用 此输入):

intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
listA - 第一个链表
listB - 第二个链表
skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数
评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。
在这里插入图片描述
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists

二、解题思路

方法一:

双指针从头遍历解法,每次移动一个位置,当一个指针指向null值时,下一次指向另一个链表的头节点,继续移动,直至两个指针指向的值相等,即为两个链表相交的节点。

开始:
在这里插入图片描述
在这里插入图片描述
最终:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA==null || headB==null) {
            return null;
        }
        ListNode p1 = headA, p2 = headB;
        while(p1!=p2) {
            // p1为null时指向另一个链表headB,否则指向下一个节点,p2同理
            p1=p1==null?headB:p1.next;
            p2=p2==null?headA:p2.next;
        }
        return p1;
    }
}

方法二:

先计算出2个链表的长度只差为n,然后将较长的链表跳过n个节点,较长链表从 n+1 个节点开始移动,短的链表从头开始移动,节点相等之处,就是交叉的节点。
在这里插入图片描述

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA==null || headB==null) {
            return null;
        }
        int lenA =0,lenB=0,diff=0;
        ListNode p1=headA,p2=headB;
        while(p1!=null){
            lenA++;
            p1=p1.next;
        }
        while(p2!=null){
            lenB++;
            p2=p2.next;
        }
        // p1用来保存较长的链表,计算两链表长度的差值diff
        if (lenA < lenB) {
            p1 = headB;
            p2 = headA;
            diff=lenB-lenA;
        }else {
            p1 = headA;
            p2 = headB;
            diff=lenA-lenB; 
        }
        for (int i=0;i<diff;i++) {
            // 较长的链表跳过diff个节点开始移动
            p1 = p1.next;
        }
        // 如果2个链表不相交,直到一个链表指针指向null,就结束循环
        while(p1!=null && p2!=null) {
            if (p1==p2) {
                return p1;
            }
            p1 = p1.next;
            p2 = p2.next;
        }
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值