LeetCode02.07面试题 链表相交 带有输入和输出的链表相交

给定两个单链表的头节点,找到它们相交的起始节点。如果无交点,则返回null。首先计算两个链表的长度,然后让较长的链表向前移动两者长度差的距离,之后同时遍历两个链表,找到第一个相同的节点即为相交节点。
摘要由CSDN通过智能技术生成

题目: 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

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

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

示例 1:
在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:
在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:
在这里插入图片描述

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例3:
在这里插入图片描述

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

思路:首先确定两个链表的长度,长的减去短的链表得到长链表需要向后移动多少位,移动后,两个链表再同时向后移动,当链表中的元素相同时结束,返回当前的元素。

#include<iostream>
using namespace std;

class MyLinkedList {
public:
	struct ListNode {
		int val;
		ListNode* next;
		ListNode(int val) :val(val), next(nullptr) {}
	};
	MyLinkedList() {
		size = 0;
		SenNode = new ListNode(0);
	}
	ListNode* addtail(int val) {
		ListNode* newNode = new ListNode(val);
		ListNode* cur = SenNode;
		while (cur->next) {
			cur = cur->next;
		}
		cur->next = newNode;
		size++;
		return SenNode->next;
	}
	ListNode* getdouble(ListNode* s1,ListNode* s2) {
		ListNode* curA = s1;
		ListNode* curB = s2;
		int lenA = 0, lenB = 0;
		while (curA) {
			lenA++;
			curA = curA->next;
		}
		//cout << lenA << " ";
		while (curB) {
			lenB++;
			curB = curB->next;
		}
		//cout << lenB << " ";
		curA = s1;
		curB = s2;

		if (lenB > lenA) {
			swap(lenA, lenB);
			swap(curA, curB);
		}
		int gap = lenA - lenB;
		while (gap--) {
			curA = curA->next;
		}
		while (curA!=NULL) {
			if (curA->val == curB->val) {
				//不然会打印后边的
				curA->next = NULL;
				return curA;
			}
			curA = curA->next;
			curB = curB->next;
		}
		return NULL;
	}

	void printList(ListNode* s1) {
		ListNode* cur = s1;
		while (cur) {
			cout << cur->val << "->";
			cur = cur->next;
		}
		
		cout << "NULL" << endl;
		cout << "length:" << size << endl;
	}
private:
	int size;
	ListNode* SenNode;
};

int main() {
	MyLinkedList s1;
	
	MyLinkedList::ListNode* node1 = s1.addtail(0);
	s1.addtail(9);
	s1.addtail(1);
	s1.addtail(2);
	s1.addtail(4);
	s1.printList(node1);
	MyLinkedList s2;
	MyLinkedList::ListNode* node2 = s2.addtail(3);
	s2.addtail(2);
	s2.addtail(4);
	s2.printList(node2);
	MyLinkedList ss;
	MyLinkedList::ListNode* result = ss.getdouble(node1, node2);
	ss.printList(result);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值