找两个链表的公共节点

首先考虑两个链表无环的情况。

将链表a的尾节点指向头节点从而形成环。用快慢指针遍历链表b,一个一次移动2单位,另一个移动1单位。如果不相遇则不存在公共节点。如果相遇,则让其中一个指针指向b,两个指针以1单位/次的速度移动,直到相遇。相遇时指向的节点就是公共节点的起始。最后记得将a的尾节点恢复。代码如下。

其次考虑有环的情况。用快慢指针探测a中是否有环。如果有则,将使p指向a的尾节点,p的next指向null。按照上面的方法遍历b。如果遍历的过程中遇到p,则将p指向a继续遍历。如果未遇到p或者无环,则不存在公共节点。最后仍然将a的尾节点恢复。

static class LinkedList {
    LinkedList next;
    public LinkedList(LinkedList next) {
        this.next = next;
    }
}

static LinkedList calc(LinkedList a, LinkedList b) {
    // set tail point to a
    LinkedList p = a;
    while (p.next != null) {
        p = p.next;
    }
    p.next = a;

    if (b == null || b.next == null)
        return null;
    LinkedList fast = b.next.next, slow = b.next;
    while (fast != null && fast.next != null && fast != slow) {
        fast = fast.next.next;
        slow = slow.next;
    }
    if (fast != slow) {
        return p.next = null;
    } else {
        slow = b;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        p.next = null;
        return slow;
    }
}

public static void main(String[] args) {
    LinkedList common = new LinkedList(new LinkedList(new LinkedList(null)));
    LinkedList a = new LinkedList(new LinkedList(common));
    LinkedList b = new LinkedList(new LinkedList(new LinkedList(
            new LinkedList(common))));
    LinkedList r = calc(a, b);
    System.out.println(r == common);

}
时间: 2024-12-29 18:32:58

找两个链表的公共节点的相关文章

【32】计算两个链表的公共长度

题目:给定两个链表的头结点,求两个链表的公共长度. 分析: 1. 两个链表无非就两种关系(其它特殊关系都可以看成是这两种的特殊关系)    (1)不相交:          (2)相交:         2. 对于第一种情况,两个链表不相交则公共长度为0.第二种情况是从第一个公共结点之后所有点都是公共的,因此可以求出公共长度. 3. 怎么求两个链表公共长度呢?     假设链表1的长度为n,链表2的长度为m,并且满足n > m.我们可以设置两个指针p1,p2开始指向链表1和链表2的头结点,并且让

剑指offer系列之三十五:两个链表的第一个公共节点

题目描述 输入两个链表,找出它们的第一个公共结点. 由于是单链表,所以可以发现从第一个公共节点开始,后面的结点都是相同的,一种思路是从两个链表的尾部开始遍历,直到发现最后一个相同的结点为止,那么这最后一个相同的结点是单链表的角度看就是两个链表的第一个公共节点了.还有一种思路是不需要从尾部开始遍历,毕竟从尾部遍历单链表的话还得使用反转链表的方法进行操作,首先计算出两个链表的长度,让更长的那个单链表先移动两个链表长度差值个位置,然后两个链表同时移动,从更短的那个链表的第一个位置开始遍历,两个链表都往

如何求两个链表的第一个公共结点

题目: 输入两个链表, 找出它们的第一个公共结点. 计算链表的长度, 然后移动较长链表的指针, 使其到相同结点的距离的相同, 再同时移动两个链表的指针, 找到相同元素. 时间复杂度: O(n) 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> #include <stdlib.h> #include <stri

C++将二叉树转为双向链表及判断两个链表是否相交_C 语言

把二叉查找树转变成排序的双向链表例如: 转换成双向链表 4=6=8=10=12=14=16 struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node }; 首先阐述下二叉排序树: 它首先要是一棵二元树,在这基础上它或者是一棵空树:或者是具有下列性质的二元树: (1)若左子树不空,

探讨:将两个链表非降序合并为一个链表并依然有序的实现方法_C 语言

已知两个链表list1和list,2,各自非降序排列,将它们合并成另外一个链表list3,并且依然有序,要求保留所有节点.实现过程中,list1中的节点和list2中的节点都转移到了list3中,注意泛型的友元函数的用法.程序如有不足之处,还望指正!!!定义List类 复制代码 代码如下: #include "stdafx.h"#include <iostream> using namespace std;template<class T>struct Node

c语言-链表中的节点的数据域可以直接插入结构体吗?打印时要怎么写呢?

问题描述 链表中的节点的数据域可以直接插入结构体吗?打印时要怎么写呢? 链表中的节点的数据域可以直接插入结构体吗?如下: struct student { int num; char name[10]; int grade; }; struct stunode { struct student; struct stunode * next; }; 如果这样可以的话,打印时要怎样写呢?(见最后几行,事实证明这样写是不可能成功的...)求指点 #include<stdio.h> #include&

逆转交替合并两个链表的解析与实现_java

逆转交替合并两个链表,即从一个链表的尾指针指向另一个链表的尾指针,依次逆转交替进行合并.下面就通过实例来详细的介绍该逆转交替合并两个链表的思路与实现代码. 一.问题描述 链表A和B A: 1->2->3->4 B: a->b->c->d 请逆转交替合并两个链表,示例结果如下: 4->d->3->c->2->b->1->a 节点类型定义如下: classNode { public Node next; ... } 二.源代码: 传

c c++-数据结构中用C++怎么把两个链表合成一个链表,一下是一对代码,请问主函数怎么写

问题描述 数据结构中用C++怎么把两个链表合成一个链表,一下是一对代码,请问主函数怎么写 求代码!#include template struct Node { DataType data; Node*next; }; template class Linklist { public: Linklist(DataType a[],int n); ~Linklist(); int Length(); DataType Get(int i); int Locate(DataType x); void

C#两个链表的二路归并怎么打?

问题描述 C#两个链表的二路归并怎么打? 老师布置的作业,上课没听懂,用一个类建立两个链表,再把两个表二路归并,求高手指导,可以的话能把详细的可以实现的代码告诉我吗?谢谢啦 解决方案 http://www.cnblogs.com/mingmingruyuedlut/archive/2011/08/18/2144984.html 解决方案二: 对了,我是大一的,没有学太多,请各位大大尽量讲简单的方法,谢谢啦