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!居然比哈希表快,真的玄学!
原文地址:https://www.jb51.cc/wenti/3284262.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。