LeetCode探索(131):1460-通过翻转子数组使两个数组相等

94 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情 >>

题目

给你两个长度相同的整数数组 targetarr 。每一步中,你可以选择 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.length
  • 1 <= target.length <= 1000
  • 1 <= target[i] <= 1000
  • 1 <= 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) 空间。

参考