1460 通过翻转子数组使两个数组相等——Leetcode天天刷(2022.8.24)【哈希表+排序】

1460 通过翻转子数组使两个数组相等——Leetcode天天刷(2022.8.24)【哈希表+排序】

前言

今天的题目,很简单,有手就行,可能是昨天的题目太难的原因,今天出的比较绿色。

看完题目就可以想到使用哈希表和排序两个解法,不过确实没想到,leetcode的执行用时属于玄学问题了,确实没想到复杂度更低的跑的更久。

题目描述

传送门

有兴趣的可以点击传送门打一下。

简单描述下题目:就是给你两个 等长数组,我们可以执行操作:选择其中一个数组的任意 非空子数组,将子数组翻转,这个操作可以执行任意次数。直到变为另外一个数组。

我们需要判断,能否使得两个数组变得一样。

示例

输入:target = [1,2,3,4], arr = [2,4,1,3]
输出:true
解释:你可以按照如下步骤使 arr 变成 target:
1- 翻转子数组 [2,4,1] ,arr 变成 [1,4,2,3]
2- 翻转子数组 [4,2] ,arr 变成 [1,2,4,3]
3- 翻转子数组 [4,3] ,arr 变成 [1,2,3,4]
上述方法并不是唯一的,还存在多种将 arr 变成 target 的方法。

输入:target = [3,7,9], arr = [3,7,11]
输出:false
解释:arr 没有数字 9 ,所以无论如何也无法变成 target 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/make-two-arrays-equal-by-reversing-sub-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

提示

在这里插入图片描述

本地调试运行

输入

我们可以假定多组输入,每组先输入一个整数n,然后接下来2行,分别输入n个整数,用来表示数组的数值。

输出

每组单行输出,如果可以操作变得一样,就输出Yes, 否则就输出No

输入样例

4
1 2 3 4
2 4 1 3

1
7
7

3
3 7 9
7 3 11

输出样例

Yes
Yes
No

解法1——哈希表

我们可以使用两个哈希表分别记录两个数组的数值出现的次数,然后再遍历一次数组比较两个哈希表。

算法比较简单,代码如下

Code(C++)

#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>

using namespace std;

class Solution 
{
public:
	// 数学,哈希表,模拟
	// 可以证明:如果数组的在数值种类和数值数量上完全相同,只是可能数值顺序不同
	// 那么彼此一定可以通过翻转得到
	// 我们使用两个哈希表,分别记录在两个数组中的数值的个数
	// 最后再遍历一次数组,比较两个哈希表
    bool canBeEqual(vector<int>& target, vector<int>& arr) 
	{
		int len1 = target.size(), len2 = arr.size();		// 获取长度
		// 优化,如果长度不同,则一定不能得到!
		if(len1 != len2)
		{
			return false;
		}
		unordered_map<int, int> cnt1, cnt2;			// 哈希表,记录数组中数值的个数
		// 循环遍历数组,记录个数
		for(int i = 0; i < len1; ++i)
		{
			++cnt1[target[i]];
			++cnt2[arr[i]];
		}
		// 再遍历一次数组,比较在两个数组中相同数值出现的个数
		for(int i = 0; i < len1; ++i)
		{
			if(cnt1[target[i]] != cnt2[target[i]])
			{
				return false;
			}
		}
		return true;
    }
};

int main()
{
	int n;
	Solution *sol = new Solution();
	while(~scanf("%d", &n))
	{
		vector<int> target(n), arr(n);
		for(int i = 0; i < n; ++i)
		{
			scanf("%d", &target[i]);
		}
		for(int i = 0; i < n; ++i)
		{
			scanf("%d", &arr[i]);
		}
		if(sol->canBeEqual(target, arr))
		{
			printf("Yes");
		}
		else
		{
			printf("No");
		}
		printf("\n");
	}
	
	delete sol;

	return 0;
}

算法分析&&运行效率

时间复杂度: O ( n ) O(n) O(n),遍历三次数组,n为数组长度。

空间复杂度: O ( n ) O(n) O(n),两个哈希表存储。

在这里插入图片描述

居然有点慢!

解法2——排序

排序就更简单了,直接将两个数组排好序,然后挨个比较就行了。

Code(C++)

#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>

using namespace std;

class Solution 
{
public:
	// 排序
	// 可以将两个数组,然后挨个比较即可
    bool canBeEqual(vector<int>& target, vector<int>& arr) 
	{
		// 排序
		sort(target.begin(), target.end());
		sort(arr.begin(), arr.end());
		int n = arr.size();
		for(int i = 0; i < n; ++i)
		{
			if(arr[i] != target[i])
			{
				return false;
			}
		}
		return true;
    }
};

int main()
{
	int n;
	Solution *sol = new Solution();
	while(~scanf("%d", &n))
	{
		vector<int> target(n), arr(n);
		for(int i = 0; i < n; ++i)
		{
			scanf("%d", &target[i]);
		}
		for(int i = 0; i < n; ++i)
		{
			scanf("%d", &arr[i]);
		}
		if(sol->canBeEqual(target, arr))
		{
			printf("Yes");
		}
		else
		{
			printf("No");
		}
		printf("\n");
	}
	
	delete sol;

	return 0;
}

算法分析&&运行效率

时间复杂度: O ( n log ⁡ n ) O(n\log{n}) O(nlogn) ,主要是排序的时间复杂度。

空间复杂度: O ( 1 ) O(1) O(1), 没啥空间开销。

在这里插入图片描述

crazy!居然比哈希表快,真的玄学!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值