力扣每日一题0824-1460. 通过翻转子数组使两个数组相等

94 阅读2分钟

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

给你两个长度相同的整数数组 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 。

哈希表判断数组元素是否相同

如果 arr\textit{arr} 长度是 11,那么只需判断 arr\textit{arr}target\textit{target} 是否相同即可。因为此时翻转非空子数组的过程并不会改变数组,只需判断原数组是否相同即可。

如果 arr\textit{arr} 长度大于 11,那么首先证明通过一次或二次翻转过程,可以实现数组 arr\textit{arr} 中任意两个元素交换位置并且保持其他元素不动。如果想要交换两个相邻元素的位置,那么翻转这两个元素组成的子数组即可。如果想要交换两个非相邻元素的位置,那么首先翻转这两个元素及其中间所有元素组成的子数组,再翻转这两个元素中间的元素组成的子数组即可。这样下来,通过一次或二次翻转过程,即可交换数组中任意两个元素的位置。一旦一个数组中任意两个元素可以交换位置,那么这个数组就能实现任意重排。只需要 arr\textit{arr}target\textit{target} 元素相同,arr\textit{arr} 就能通过若干次操作变成 target\textit{target}

var canBeEqual = function(target, arr) {
    const counts1 = new Map();
    const counts2 = new Map();
    for (const num of target) {
        counts1.set(num, (counts1.get(num) || 0) + 1);
    }
    for (const num of arr) {
        counts2.set(num, (counts2.get(num) || 0) + 1);   
    }
    if (counts1.size !== counts2.size) {
        return false;
    }
    for (const [key, value] of counts1.entries()) {
        if (!counts2.has(key) || counts2.get(key) !== value) {
            return false;
        }
    }
    return true;
};

排序判断数组元素是否相同

var canBeEqual = function(target, arr) {
    target.sort((a, b) => a - b);
    arr.sort((a, b) => a - b);
    return target.toString() === arr.toString();
};