寻找链表相交节点

思路一:

1、先求出两个链表ListA,ListB的长度LengthA,LengthB。

2、然后先把长的链表头指针先往前走|LengthA - LengthB|步。

3、最后两个链表头指针同步往前走一步,直到指向的对象相同。

代码实现及测试用例:

package com.qiusongde;

public class Solution160 {

    public static void main(String[] args) {

        ListNode l1 = new ListNode(1);
        ListNode l2 = new ListNode(2);
        ListNode l3 = new ListNode(3);
        l1.next = l2;
        l2.next = l3;

        ListNode l4 = new ListNode(4);
        ListNode l5 = new ListNode(5);
        l4.next = l5;
        l5.next = l3;

        showListNode(l1);
        showListNode(l4);
        System.out.println(getIntersectionNode(l1, l4).val);

    }

    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        if(headA == null || headB == null) {
            return null;
        }

        //compute the length of two list
        int sizeA = length(headA);
        int sizeB = length(headB);

        //counteract difference
        while(sizeA > sizeB) {
            headA = headA.next;
            sizeA--;
        }
        while(sizeB > sizeA) {
            headB = headB.next;
            sizeB--;
        }

        //find the same node
        //if no intersection, the same node is null
        while(headA != headB) {
            headA = headA.next;
            headB = headB.next;
        }

        return headA;

    }

    private static int length(ListNode node) {
        int length = 0;

        while(node != null) {
            length++;
            node = node.next;
        }

        return length;
    }

    public static void showListNode(ListNode list) {

        if(list == null) {
            System.out.println(list);
            return;
        }

        while(list != null) {
            System.out.print(list.val + " ");
            list = list.next;
        }
        System.out.println();

    }

    public static class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
            next = null;
        }
    }

}
1 2 3
4 5 3
3

思路2:

不用求出链表长度的值,但其实算法复杂度是一样的。

We can use two iterations to do that.

In the first iteration, we will reset the pointer of one linkedlist to the head of another linkedlist after it reaches the tail node.

In the second iteration, we will move two pointers until they points to the same node.

Our operations in first iteration will help us counteract the difference.

So if two linkedlist intersects, the meeting point in second iteration must be the intersection point.

If the two linked lists have no intersection at all, then the meeting pointer in second iteration must be the tail node of both lists, which is null

代码实现:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    //boundary check
    if(headA == null || headB == null) return null;

    ListNode a = headA;
    ListNode b = headB;

    //if a & b have different len, then we will stop the loop after second iteration
    while( a != b){
        //for the end of first iteration, we just reset the pointer to the head of another linkedlist
        a = a == null? headB : a.next;
        b = b == null? headA : b.next;
    }

    return a;
}

参考:https://leetcode.com/problems/intersection-of-two-linked-lists/#/solutions

时间: 2024-12-30 11:37:50

寻找链表相交节点的相关文章

链表逆序 和 寻找链表中间节点

已知链表的头节点为head,写一个函数把链表逆序. void reserve(list_node* head){ if(head == NULL) return 0; list_node* p = head; list_node* q = p->next; list_node* r = NULL; while(q){ r = q->next; q->next = p; p = q; q = r; } head->next == NULL; head = p; } 找出单链表的中间节

两个链表相交以及第一个公共节点的问题

判读两个链表是否相交以及如果相交它们的第一个公共节点的问题,主要分这么几种情况: 1)两个链表均不含有环 2)两个链表均含有环 对于一个有环一个没有,那么它们即不相交也没有公共节点 首先定义节点的结构 struct Node { int value; Node *next; }; 判断链表是否有环函数 bool isRingList(Node *head) { if(NULL == head) return false; Node *p1 = head, *p2 = p1->next; whil

单向链表的查删改功能,以及约瑟夫环,相交链表的第一个相交节点的查找等相关问题

slist.h//头文件 #ifndef _SLIST_H_ #define _SLTST_H_ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> typedef int SLTDataType; typedef struct SListNode { SLTDataType data; struct SListNode* next; }SListNode; voi

C语言强化(七)链表相交问题_1 判断无环链表相交

从此篇博文开始,讲解一道古老的链表相交问题,共五篇 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 此篇先从最简单的判断两个[无环]链表是否相交开始,顺便介绍一下链表的基础知识,方便一些对链表不太了解的同学学习. 基础知识 什么是链表? 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指

如何判断链表相交

链表相交:对于链表而言,两个链表如果相交就会合并成一个后继,之后后继成为一个链表.根据相交的理论可以建立出两个简单的链表相交. 当用户在第一个链表中输入10的那个点作为要相交的那个点,第二个链表输入零之后就与第一个链表的10那个点相交. 代码如下: 1 #include <stdio.h> 2 typedef struct Linklist{ 3 int num; 4 struct Linklist *next; 5 }list; 6 7 struct Linklist *in; 8 9 vo

链表相交问题:判断两个链表是否相交,若相交求交点

默认为不带环链表,若带环则延伸为判断链表是否带环,若带环,求入口点 看看两个链表相交到底是怎么回事吧,有这样的的几个事实:(假设链表中不存在环) (1)一旦两个链表相交,那么两个链表中的节点一定有相同地址. (2)一旦两个链表相交,那么两个链表从相交节点开始到尾节点一定都是相同的节点. #include<iostream> #include<assert.h> using namespace std; template<class T> struct LinkNode

C语言强化(七)链表相交问题_3 判断链表是否带环

前两篇讨论的前提都是链表是无环的,但是如果链表有环呢? 显然,如果链表有环,那么之前的寻找链表尾结点的函数将陷入死循环,之前的算法也将崩掉. 所以对于链表相交的问题,首先要判断的是链表是否有环. 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路 用两个指针,一个指针步长为1,一个指针步长为2,若最后相遇,则链表有环

C语言强化(七)链表相交问题_4 判断两个有环链表是否相交

上一节结束后,我们已经可以判断链表是否有环了,如果无环,那么按照前两节所讲的方法去判断链表是否相交以及获取相交结点,如果有环呢?怎么判断是否相交? 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路 对于有环的链表,只要它们相交,则带环的那一段必定完全重复.所以我们只需要在链表一上找到环上的一个结点,判断该结点是否在链

C语言强化(七)链表相交问题_2 找到无环链表相交结点

上一节聊了判断两个[无环]链表是否相交,那么如果相交,怎么找到相交结点呢? 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路 遍历的过程中记录链表的长度L1和L2(假设L1>L2) 遍历找到第一个链表中的第L1 - L2节点, 链表一从第L1-L2个节点开始遍历,链表二从第一个节点遍历,相当于两链表从与相交点距离相同