C++ 解决求两个链表的第一个公共结点问题

下面我将为您详细讲解C++如何解决求两个链表的第一个公共结点问题。

问题描述

给定两个单向链表的头指针head1head2,请找出它们的第一个公共结点。

解决思路

要想求两个链表的第一个公共结点,我们可以使用如下思路:

  1. 先遍历两个链表得到它们的长度len1len2。同时标记一下两个链表的尾节点是否相同。
  2. 如果两个链表的尾节点不同,则两个链表没有公共节点,直接返回nullptr
  3. 如果两个链表的尾节点相同,则让长一点的链表的头指针先向后移动len1 - len2个节点。
  4. 然后同时遍历两个链表,直到找到第一个公共节点,如果没有公共节点则返回nullptr

代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    ListNode* FindFirstCommonNode(ListNode* head1, ListNode* head2) {
        if (!head1 || !head2) {  // 其中一个链表为空则直接返回
            return nullptr;
        }
        int len1 = getListLength(head1);
        int len2 = getListLength(head2);
        ListNode *pLong, *pShort;
        int diff;
        if (len1 > len2) {  // 长短链表分别指向
            pLong = head1;
            pShort = head2;
            diff = len1 - len2;
        } else {
            pLong = head2;
            pShort = head1;
            diff = len2 - len1;
        }
        while (diff--) {
            pLong = pLong -> next;
        }
        while (pLong && pShort && pLong != pShort) {
            pLong = pLong -> next;
            pShort = pShort -> next;
        }
        return pLong;
    }
private:
    int getListLength(ListNode* head) {
        int length = 0;
        ListNode* p = head;
        while (p) {
            ++length;
            p = p -> next;
        }
        return length;
    }
};

如上所示,我们首先判断两个链表中是否有一个为空,如果有一个为空则直接返回nullptr。然后遍历两个链表得到它们的长度,并且同时标记一下它们的尾节点是否相同。如果两个链表的尾节点不同,则直接返回nullptr。如果两个链表的尾节点相同,则让长一点的链表的头指针先向后移动len1 - len2个节点,然后同时遍历两个链表,直到找到第一个公共节点,如果没有公共节点则返回nullptr

示例说明

示例1

链表1:1 -> 2 -> 3 -> 6 -> 7
链表2:4 -> 5 -> 6 -> 7

这两个链表的第一个公共节点是6。

ListNode* head1 = new ListNode(1);
head1 -> next = new ListNode(2);
head1 -> next -> next = new ListNode(3);
ListNode* p = head1 -> next -> next;
p -> next = new ListNode(6);
p -> next -> next = new ListNode(7);

ListNode* head2 = new ListNode(4);
head2 -> next = new ListNode(5);
p = head2 -> next;
p -> next = head1 -> next -> next -> next;

Solution sol;
ListNode* res = sol.FindFirstCommonNode(head1, head2);
cout << res -> val << endl;  // 输出 6

示例2

链表1:1 -> 2 -> 3
链表2:4 -> 5 -> 6 -> 7

这两个链表没有公共节点。

ListNode* head1 = new ListNode(1);
head1 -> next = new ListNode(2);
head1 -> next -> next = new ListNode(3);

ListNode* head2 = new ListNode(4);
head2 -> next = new ListNode(5);
ListNode* p = head2 -> next;
p -> next = new ListNode(6);
p = p -> next;
p -> next = new ListNode(7);

Solution sol;
ListNode* res = sol.FindFirstCommonNode(head1, head2);
cout << res << endl;  // 输出 nullptr

以上就是C++解决求两个链表的第一个公共结点问题的完整攻略,希望对您有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 解决求两个链表的第一个公共结点问题 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • linux系统下的df命令参数详解

    Linux系统下的df命令参数详解攻略 介绍 df(磁盘空间查看器)是一个Linux系统下的命令行工具,用于显示文件系统的可用空间大小。本攻略将详细介绍df命令的参数及其用法。 命令语法 df [选项]… [文件]… 参数解释 以下是df命令常用的选项参数: -a, –all:显示所有文件系统,包括/proc等伪文件系统; -B, –block-…

    other 2023年6月27日
    00
  • Angular directive递归实现目录树结构代码实例

    Angular directive递归实现目录树结构是一个非常实用的功能,可以让我们更加方便地展示数据,使用户更好地理解数据结构。接下来我将为大家提供一份完整的攻略,教大家如何实现这个功能。 目录 1.什么是Angular directive递归2.如何实现Angular directive递归3. 如何使用Angular directive递归实现目录树结…

    other 2023年6月27日
    00
  • JS实现非首屏图片延迟加载的示例

    JS实现非首屏图片延迟加载可以提高网站的性能,避免一次性加载全部图片对网站造成的压力,下面详细介绍实现的攻略: 1. 了解非首屏图片延迟加载 首先需要了解什么是非首屏图片延迟加载,它的原理是在网站的加载过程中,只加载当前屏幕所需展示的图片,等到用户滚动到相应位置时再加载相应的图片。这样做可以减少首屏加载时间,提高网站加载速度。 2. 实现延迟加载的JS代码 …

    other 2023年6月25日
    00
  • Java JDK11基于嵌套的访问控制的实现

    Java JDK11基于嵌套的访问控制的实现攻略 Java JDK 11引入了基于嵌套的访问控制,这是一种新的访问控制机制,可以更好地管理类和接口之间的访问权限。本攻略将详细介绍如何使用这一特性,并提供两个示例说明。 1. 嵌套访问控制的概述 嵌套访问控制是指在类或接口内部定义的嵌套类或嵌套接口之间的访问权限控制。在Java中,有四种访问修饰符:public…

    other 2023年7月28日
    00
  • python实现双链表

    实现双链表需要明确双链表的特点:每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。双链表的操作包括插入、删除、查找等。接下来,我将详细讲解如何在Python中实现双链表。 1. 定义节点类 class Node: def __init__(self, data): self.data = data # 数据 self.prev = None # …

    other 2023年6月27日
    00
  • C语言中#pragma once的作用

    C语言中#pragma once是用于防止头文件被重复引用的一种预处理指令。下面详细讲解它的作用和使用方法。 一、作用 #pragma once的作用是用于防止C/C++程序中的头文件被重复引用。头文件中常常定义了一些宏、类型和函数等,当一个头文件被多次引用时就会产生重复定义的错误。使用#pragma once能够保证同一头文件只在编译器中被包含一次,从而避…

    other 2023年6月26日
    00
  • Android学习之基础知识四-Activity活动8讲(活动的灵活运用)

    Android学习之基础知识四-Activity活动8讲(活动的灵活运用) 在Android开发中,Activity是非常重要的一个组件,它负责用户界面的呈现和事件响应。在之前的文章中,我们已经学习了Activity的基础知识,本篇文章将为大家介绍Activity的灵活运用技巧,帮助大家更好地开发应用程序。 1. 启动Activity Activity的启动…

    其他 2023年3月28日
    00
  • 易语言自定义外形按钮实现过程

    下面我就为您详细讲解易语言自定义外形按钮的实现过程。 什么是自定义外形按钮? 自定义外形按钮是指在易语言窗口中添加特定形状和样式的按钮,与普通按钮相比,自定义外形按钮能够更好的展现设计者的个性和创意。 实现过程 以下是自定义外形按钮的实现过程: 1. 创建按钮控件 在易语言中创建一个按钮控件,并设置该按钮的位置、大小、名称等属性。可以使用以下代码实现: ‘定…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部