列表

详情


1764. 通过连接另一个数组的子数组得到一个数组

给你一个长度为 n 的二维整数数组 groups ,同时给你一个整数数组 nums 。

你是否可以从 nums 中选出 n 个 不相交 的子数组,使得第 i 个子数组与 groups[i] (下标从 0 开始)完全相同,且如果 i > 0 ,那么第 (i-1) 个子数组在 nums 中出现的位置在第 i 个子数组前面。(也就是说,这些子数组在 nums 中出现的顺序需要与 groups 顺序相同)

如果你可以找出这样的 n 个子数组,请你返回 true ,否则返回 false 。

如果不存在下标为 k 的元素 nums[k] 属于不止一个子数组,就称这些子数组是 不相交 的。子数组指的是原数组中连续元素组成的一个序列。

 

示例 1:

输入:groups = [[1,-1,-1],[3,-2,0]], nums = [1,-1,0,1,-1,-1,3,-2,0]
输出:true
解释:你可以分别在 nums 中选出第 0 个子数组 [1,-1,0,1,-1,-1,3,-2,0] 和第 1 个子数组 [1,-1,0,1,-1,-1,3,-2,0] 。
这两个子数组是不相交的,因为它们没有任何共同的元素。

示例 2:

输入:groups = [[10,-2],[1,2,3,4]], nums = [1,2,3,4,10,-2]
输出:false
解释:选择子数组 [1,2,3,4,10,-2] 和 [1,2,3,4,10,-2] 是不正确的,因为它们出现的顺序与 groups 中顺序不同。
[10,-2] 必须出现在 [1,2,3,4] 之前。

示例 3:

输入:groups = [[1,2,3],[3,4]], nums = [7,7,1,2,3,4,7,7]
输出:false
解释:选择子数组 [7,7,1,2,3,4,7,7] 和 [7,7,1,2,3,4,7,7] 是不正确的,因为它们不是不相交子数组。
它们有一个共同的元素 nums[4] (下标从 0 开始)。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: bool canChoose(vector<vector<int>>& groups, vector<int>& nums) { } };

java 解法, 执行用时: 0 ms, 内存消耗: 41.9 MB, 提交时间: 2022-12-17 15:41:32

class Solution {
    public boolean canChoose(int[][] groups, int[] nums) {
        int p1 = 0, p2, n = nums.length;
        for (int[] g : groups) {
            p2 = 0;
            while (p2 < g.length && p1 < n) {
                if (nums[p1++] == g[p2]) p2++;
                else {p1 -= p2; p2 = 0;} //回到开头的下一个数字重新开始
            }
            if (p2 != g.length) return false;
        }
        return true;
    }
}

javascript 解法, 执行用时: 68 ms, 内存消耗: 43.6 MB, 提交时间: 2022-12-17 15:40:55

/**
 * @param {number[][]} groups
 * @param {number[]} nums
 * @return {boolean}
 */
var canChoose = function(groups, nums) {
    let k = 0;
    for (let i = 0; i < groups.length; i++) {
        k = find(nums, k, groups[i]);
        if (k == -1) {
            return false;
        }
        k += groups[i].length;
    }
    return true;
}

const find = (nums, k, g) => {
    let m = g.length, n = nums.length;
    if (k + g.length > nums.length) {
        return -1;
    }
    const pi = new Array(m).fill(0);
    for (let i = 1, j = 0; i < m; i++) {
        while (j > 0 && g[i] !== g[j]) {
            j = pi[j - 1];
        }
        if (g[i] === g[j]) {
            j++;
        }
        pi[i] = j;
    }
    for (let i = k, j = 0; i < n; i++) {
        while (j > 0 && nums[i] !== g[j]) {
            j = pi[j - 1];
        }
        if (nums[i] === g[j]) {
            j++;
        }
        if (j === m) {
            return i - m + 1;
        }
    }
    return -1;
};

java 解法, 执行用时: 0 ms, 内存消耗: 41.7 MB, 提交时间: 2022-12-17 15:40:43

class Solution {
    public boolean canChoose(int[][] groups, int[] nums) {
        int k = 0;
        for (int i = 0; i < groups.length; i++) {
            k = find(nums, k, groups[i]);
            if (k == -1) {
                return false;
            }
            k += groups[i].length;
        }
        return true;
    }

    public int find(int[] nums, int k, int[] g) {
        int m = g.length, n = nums.length;
        if (k + g.length > nums.length) {
            return -1;
        }
        int[] pi = new int[m];
        for (int i = 1, j = 0; i < m; i++) {
            while (j > 0 && g[i] != g[j]) {
                j = pi[j - 1];
            }
            if (g[i] == g[j]) {
                j++;
            }
            pi[i] = j;
        }
        for (int i = k, j = 0; i < n; i++) {
            while (j > 0 && nums[i] != g[j]) {
                j = pi[j - 1];
            }
            if (nums[i] == g[j]) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;
    }
}

python3 解法, 执行用时: 40 ms, 内存消耗: 15.1 MB, 提交时间: 2022-12-17 15:40:12

class Solution:
    def canChoose(self, groups: List[List[int]], nums: List[int]) -> bool:
        k = 0
        for g in groups:
            while k + len(g) <= len(nums):
                if nums[k: k + len(g)] == g:
                    k += len(g)
                    break
                k += 1
            else:
                return False
        return True

golang 解法, 执行用时: 8 ms, 内存消耗: 4.8 MB, 提交时间: 2022-12-17 15:39:12

func canChoose(groups [][]int, nums []int) bool {
next:
	for _, g := range groups {
		for len(nums) >= len(g) {
			if equal(nums[:len(g)], g) {
				nums = nums[len(g):]
				continue next
			}
			nums = nums[1:]
		}
		return false
	}
	return true
}

func equal(a, b []int) bool {
	for i, x := range a {
		if x != b[i] {
			return false
		}
	}
	return true
}

javascript 解法, 执行用时: 72 ms, 内存消耗: 41.9 MB, 提交时间: 2022-12-17 15:38:59

/**
 * @param {number[][]} groups
 * @param {number[]} nums
 * @return {boolean}
 */
var canChoose = function(groups, nums) {
    let i = 0;
    for (let k = 0; k < nums.length && i < groups.length;) {
        if (check(groups[i], nums, k)) {
            k += groups[i].length;
            i++;
        } else {
            k++;
        }
    }
    return i === groups.length;
}

const check = (g, nums, k) => {
    if (k + g.length > nums.length) {
        return false;
    }
    for (let j = 0; j < g.length; j++) {
        if (g[j] !== nums[k + j]) {
            return false;
        }
    }
    return true;
};

java 解法, 执行用时: 0 ms, 内存消耗: 41.8 MB, 提交时间: 2022-12-17 15:38:45

class Solution {
    public boolean canChoose(int[][] groups, int[] nums) {
        int i = 0;
        for (int k = 0; k < nums.length && i < groups.length;) {
            if (check(groups[i], nums, k)) {
                k += groups[i].length;
                i++;
            } else {
                k++;
            }
        }
        return i == groups.length;
    }

    public boolean check(int[] g, int[] nums, int k) {
        if (k + g.length > nums.length) {
            return false;
        }
        for (int j = 0; j < g.length; j++) {
            if (g[j] != nums[k + j]) {
                return false;
            }
        }
        return true;
    }
}

cpp 解法, 执行用时: 8 ms, 内存消耗: 13.1 MB, 提交时间: 2022-12-17 15:38:34

class Solution {
public:
    bool check(vector<int> &g, vector<int> &nums, int k) {
        if (k + g.size() > nums.size()) {
            return false;
        }
        for (int j = 0; j < g.size(); j++) {
            if (g[j] != nums[k + j]) {
                return false;
            }
        }
        return true;
    }

    bool canChoose(vector<vector<int>>& groups, vector<int>& nums) {
        int i = 0;
        for (int k = 0; k < nums.size() && i < groups.size();) {
            if (check(groups[i], nums, k)) {
                k += groups[i].size();
                i++;
            } else {
                k++;
            }
        }
        return i == groups.size();
    }
};

上一题