携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情 >>
题目
给你两个长度相同的整数数组 target 和 arr 。每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转。你可以执行此过程任意次。
如果你能让 arr 变得与 target 相同,返回 True;否则,返回 False 。
示例 1:
输入: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 的方法。
示例 2:
输入:target = [7], arr = [7]
输出:true
解释:arr 不需要做任何翻转已经与 target 相等。
示例 3:
输入:target = [3,7,9], arr = [3,7,11]
输出:false
解释:arr 没有数字 9 ,所以无论如何也无法变成 target 。
提示:
target.length == arr.length1 <= target.length <= 10001 <= target[i] <= 10001 <= arr[i] <= 1000
思考
本题难度简单。
首先是读懂题意。题目中注明整数数组target和arr的元素个数相等。在每一步操作时,可以选择 arr 的任意 非空子数组 并将它翻转。你可以执行此过程任意次。
我们不难得出,可以通过任意次操作,使得任意数组target和arr都按照从小到大的顺序排列。因此,我们只需要比较数组target和arr的元素种类和相同元素对应的数量是否相等即可。所以,我们可以使用哈希表解题。
解答
方法一:哈希表
/**
* @param {number[]} target
* @param {number[]} arr
* @return {boolean}
*/
var canBeEqual = function(target, arr) {
let map1 = new Map(), map2 = new Map()
for (let i = 0; i < target.length; i++) {
map1.set(target[i], (map1.get(target[i]) || 0) + 1)
map2.set(arr[i], (map2.get(arr[i]) || 0) + 1)
}
if (map1.size !== map2.size) {
return false
}
for (let [num, count] of map1.entries()) {
if (!map2.has(num) || map2.get(num) !== count) {
return false
}
}
return true
}
复杂度分析:
- 时间复杂度:O(n),其中 n 是输入数组的长度,统计并判断频次是否相同消耗 O(n)。
- 空间复杂度:O(n),哈希表最多消耗 O(n) 空间。