前端算法第一八七弹-能否连接形成数组

81 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

给你一个整数数组 arr ,数组中的每个整数 互不相同 。另有一个由整数数组构成的数组 pieces,其中的整数也 互不相同 。请你以 任意顺序 连接 pieces 中的数组以形成 arr 。但是,不允许 对每个数组 pieces[i] 中的整数重新排序。

如果可以连接 **pieces 中的数组形成 arr ,返回 true ;否则,返回 false

示例 1:

输入:arr = [15,88], pieces = [[88],[15]]
输出:true
解释:依次连接 [15] 和 [88]

示例 2:

输入:arr = [49,18,16], pieces = [[16,18,49]]
输出:false
解释:即便数字相符,也不能重新排列 pieces[0]

示例 3:

输入:arr = [91,4,64,78], pieces = [[78],[4,64],[91]]
输出:true
解释:依次连接 [91][4,64][78]

因为arr中的整数互不相同,pieces中的整数也互不相同。所以我们只需要遍历arr数组,并找到pieces中的数组第一个值与之相同,就能找到pieces中的那个需要遍历的数组,并且将该数组在pieces中删除。 最后遍历完arr数组,判断如果pieces数组为空,那么两者数字相同。

/**
 * @param {number[]} arr
 * @param {number[][]} pieces
 * @return {boolean}
 */
var canFormArray = function(arr, pieces) {
    for(let i = 0; i < arr.length;) {
        let num = arr[i]
        let pIndex = pieces.findIndex(p => p[0] == num)
        if (pIndex < 0)  return false
        else {
            let pArr = pieces.splice(pIndex, 1)[0]
            for (let j = 0; j < pArr.length; j++) {
                if (pArr[j] !== arr[i]) return false
                else i++; 
            }
        }
    }
    return pieces.length == 0
};

复杂度分析

  • 时间复杂度:O(n),其中 n 为 输入 arr 数组的长度。
  • 空间复杂度:O(1)。

与解法1类似,我们还可以使用map预存,替换找到pieces中的数组的过程。

/**
 * @param {number[]} arr
 * @param {number[][]} pieces
 * @return {boolean}
 */
var canFormArray = function(arr, pieces) {
    let map = new Map()
    for (let piece of pieces) {
        map.set(piece[0], piece)
    }
    for(let i = 0; i < arr.length;) {
        let num = arr[i]
        if (!map.has(num)) return false
        let pArr = map.get(num)
        for (let j = 0; j < pArr.length; j++) {
            if (pArr[j] !== arr[i]) return false
            else i++; 
        }
    }
    return true
};