每日一练——7-52 两个有序链表序列的交集(20 分)

156 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情

题目描述:

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 2 5 -1
2 4 5 8 10 -1

输出样例:

2 5

代码长度限制   16 KB

时间限制     400 ms

内存限制     64 MB

题目分析

刚开始的时候是不是有的同学想到了直接用数组来实现,但是你会发现这是一个动态的数组,所以需要一个动态的容器,动态容器有vector、deque、list这几个比较采用,看了我昨天的C++硬货——list头文件的话,我认为list容器在这题是比较好用的~我们只需要根据题目的思路来进行编程(数据结构给大家的不只是代码,更是思维过程)~

步骤

  • 1.创建两个list容器来存放这两行的数据
  • 2.创建两个关于这两个容器的头部迭代器
  • 3.进行遍历,当他们两个都没到达末尾为循环条件
  • 4.如果元素的值相同,l3存数字,这两个迭代器同时先前移动
  • 5.如果这两个元素的值不同,我们只要找到小的那个,让小的迭代器先前移动
  • 6.输出l3

代码如下:

#include<iostream>
#include<list>
using namespace std;
int main()
{
	list<int>l1, l2, l3;
	int x;
	cin >> x;
	//对l1进行尾插
	while (x != -1) {
		l1.push_back(x);
		cin >> x;
	}
	//对l2进行尾插
	cin >> x;
	while (x != -1) {
		l2.push_back(x);
		cin >> x;
	}
	//创建两个迭代器,用于关联l1和l2
	list<int>::iterator it1 = l1.begin(), it2 = l2.begin();

	//当两个链表均未到达末尾时,不断地进行移动
	while (it1 != l1.end() && it2 != l2.end()) {
		//如果找到了交集
		if (*it1 == *it2) {
			l3.push_back(*it1);
			it1++;
			it2++;
		}
		//如果没找到交集
		else {
			//如l1的元素比l2的元素小
			if (*it1 < *it2)
				it1++;
			//如l2的元素比l1的元素小
			else
				it2++;
		}
	}
	if (l3.empty()) {
		cout << "NULL";
	}
	else {
		list<int>::iterator it3 = l3.begin();
		cout << *it3;
		it3++;
		while (it3 != l3.end()) {
			cout << " " << *it3;
			it3++;
		}
	}
}

各测试点分值:

image.png