• 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
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    提示

    在这里插入图片描述

    本地调试运行

    输入

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

    输出

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

    输入样例

    4
    1 2 3 4
    2 4 1 3
    
    1
    7
    7
    
    3
    3 7 9
    7 3 11
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出样例

    Yes
    Yes
    No
    
    • 1
    • 2
    • 3

    解法1——哈希表

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

    算法比较简单,代码如下

    Code(C++)

    #include
    #include
    #include
    #include
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    算法分析&&运行效率

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

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

    在这里插入图片描述

    居然有点慢!

    解法2——排序

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

    Code(C++)

    #include
    #include
    #include
    #include
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    算法分析&&运行效率

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

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

    在这里插入图片描述

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

  • 相关阅读:
    Linux系统IO和标准IO的接口函数
    数智转型,管理先行|JNPF全力打造“全生命周期管理”平台
    CCF ChinaSoft 2023 论坛巡礼 | 云计算标准化论坛
    基于restful页面数据交互(前端页面访问处理)
    vue-ant design示例大全——按钮本地css/js资源
    【JS】js数字转k、w结尾 | 1000 = 1k
    热门Java开发工具IDEA入门指南——初次运行IntelliJ IDEA
    (附源码)计算机毕业设计ssm-Java网名推荐系统
    【WinSCP】强大的可视化远程文件传输 、管理工具 (支持多种协议,支持电脑与手机)
    vi 连线板.
  • 原文地址:https://blog.csdn.net/weixin_54891898/article/details/126502739