LeetCode-1743. 从相邻元素对还原数组

241 篇文章 1 订阅
210 篇文章 0 订阅

存在一个由 n 个不同元素组成的整数数组 nums ,但你已经记不清具体内容。好在你还记得 nums 中的每一对相邻元素。

给你一个二维整数数组 adjacentPairs ,大小为 n - 1 ,其中每个 adjacentPairs[i] = [ui, vi] 表示元素 ui 和 vi 在 nums 中相邻。

题目数据保证所有由元素 nums[i] 和 nums[i+1] 组成的相邻元素对都存在于 adjacentPairs 中,存在形式可能是 [nums[i], nums[i+1]] ,也可能是 [nums[i+1], nums[i]] 。这些相邻元素对可以 按任意顺序 出现。

返回 原始数组 nums 。如果存在多种解答,返回 其中任意一个 即可。

示例 1:

输入:adjacentPairs = [[2,1],[3,4],[3,2]]
输出:[1,2,3,4]
解释:数组的所有相邻元素对都在 adjacentPairs 中。
特别要注意的是,adjacentPairs[i] 只表示两个元素相邻,并不保证其 左-右 顺序。
示例 2:

输入:adjacentPairs = [[4,-2],[1,4],[-3,1]]
输出:[-2,4,1,-3]
解释:数组中可能存在负数。
另一种解答是 [-3,1,4,-2] ,也会被视作正确答案。
示例 3:

输入:adjacentPairs = [[100000,-100000]]
输出:[100000,-100000]
 

提示:

nums.length == n
adjacentPairs.length == n - 1
adjacentPairs[i].length == 2
2 <= n <= 105
-105 <= nums[i], ui, vi <= 105
题目数据保证存在一些以 adjacentPairs 作为元素对的数组 nums

真的是脑筋急转弯。

#include <iostream>
#include <vector>
#include <map>
#include <set>
using namespace std;


/*
 * 假设数据为[[4, -2], [1, 4], [-3, 1]]
 * 考虑哈希表(需要支持重复键的map)中存储:
 * [4] = -2 , [-2] = 4
 * [1] = 4  , [4] = 1
 * [-3] = 1 , [1] = -3
 * 因为其中相邻的意思是,首部和尾部相邻的值肯定只有1个。中间的值为两个
 * 上述结构在数据结构中存储为
 *  4 对应, -2, 1
 * -2 对应, 4
 *  1 对应, 4, -3
 * -3 对应, 1
 * 从中我们可以知道 -2,4 和 -3,1肯定为首尾
 * 那么我们可以选择任意一个来算,比如选择 -3,1
 * -3存入,1存入,然后以1作为key,可以查到 4,-3
 * 4之前没存过,存入,并更新key = 4, -3已经存入不再存入
 * 然后查询得到 -2和1,-2没存过,存入,并更新key = -2,
 * 而1已经存入,不再存入,然后查询key=-2得值,得到4,4已经存入。循环结束
 */




class SourceClass {

public:
	friend class Solution;

	vector<int> getResult(vector<vector<int>>& adjacentPairs) {
		mset.clear();
		vector<int> HL;  /* 头部和尾部 */
		vector<int> res;
		bool isChkSecond = false;

		/* 存取一次mp[key]=val 并存取 mp[val]=key */
		for (int i = 0; i < adjacentPairs.size(); i++) {
			mp.insert(make_pair(adjacentPairs[i][0], adjacentPairs[i][1]));
			mp.insert(make_pair(adjacentPairs[i][1], adjacentPairs[i][0]));
		}

		for (auto it = mp.begin(); it != mp.end(); it++) {
			auto n = mp.count(it->first);
			if (n == 1) {
				HL.push_back(it->first);
			}
		}

		//for (int i = 0; i < HL.size(); i++) {
		//	cout << "HL[" << i << "]" << HL[i] << endl;
		//}


		int key = HL[0];


		while (1) {
			auto eqIt = mp.equal_range(key);
			isChkSecond = false;   /* 如果第second值,一次都没走说明已经到末尾了,说明所有数据全部插入完了 */

			for (auto eqIter = eqIt.first; eqIter != eqIt.second; ++eqIter) {

				//cout << eqIter->first << " is " << eqIter->second << std::endl;
				if (mset.count(eqIter->first) == 0) {
					mset.insert(eqIter->first);
					res.push_back(eqIter->first);
				}
				if (mset.count(eqIter->second) == 0) {
					mset.insert(eqIter->second);
					res.push_back(eqIter->second);
					key = eqIter->second;
					isChkSecond = true;
				}
			}

			if (!isChkSecond) {
				break;
			}
		}
		return res;
	}

private:
	multimap<int, int> mp;
	set<int> mset;
};

class Solution {
public:
	vector<int> restoreArray(vector<vector<int>>& adjacentPairs) {
		SourceClass s;
		return s.getResult(adjacentPairs);
	}

};

int main() {
	Solution* ps = new Solution();
	//vector<vector<int>> adjacentPairs = { {2, 1},{3, 4},{3, 2} };
	vector<vector<int>> adjacentPairs = { {4, -2},{1, 4},{-3, 1} };

	vector<int> res = ps->restoreArray(adjacentPairs);

	for (int i = 0; i < res.size(); i++) {
		cout << res[i] << endl;
	}

	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值