使用变量 i 指向需要匹配的数组,即 groups}[i]。遍历数组 nums,假设当前遍历到第 k 个元素:
以 nums}[k] 为首元素的子数组与 groups}[i] 相同,那么 groups}[i] 可以找到对应的子数组。为了满足不相交的要求,我们将 k 加上数组 groups}[i] 的长度,并且将 i 加 1;
以 nums}[k] 为首元素的子数组与 groups}[i] 不相同,那么我们直接将 k 加 1。
遍历结束时,如果 groups 的所有数组都找到对应的子数组,即 i = n 成立,返回 true;否则返回 false。
贪心的正确性
证明:假设存在 n 个不相交的子数组,使得第 i 个子数组与 groups}[i] 完全相同,并且第 i 个子数组的首元素下标为 k,那么在匹配查找的过程中,如果存在下标 k_1 \lt k 也满足第 i 个子数组的要求,显然我们将 k_1 替代 k 是不影响后续的匹配的。
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defcanChoose(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: returnFalse returnTrue
classSolution { public: boolcheck(vector<int> &g, vector<int> &nums, int k){ if (k + g.size() > nums.size()) { returnfalse; } for (int j = 0; j < g.size(); j++) { if (g[j] != nums[k + j]) { returnfalse; } } returntrue; }
boolcanChoose(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(); } };
publicclassSolution { publicboolCanChoose(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; }
publicboolCheck(int[] g, int[] nums, int k) { if (k + g.Length > nums.Length) { returnfalse; } for (int j = 0; j < g.Length; j++) { if (g[j] != nums[k + j]) { returnfalse; } } returntrue; } }
boolcheck(constint *g, int gSize, constint *nums, int numsSize, int k) { if (k + gSize > numsSize) { returnfalse; } for (int j = 0; j < gSize; j++) { if (g[j] != nums[k + j]) { returnfalse; } } returntrue; }
boolcanChoose(int** groups, int groupsSize, int* groupsColSize, int* nums, int numsSize) { int i = 0; for (int k = 0; k < numsSize && i < groupsSize;) { if (check(groups[i], groupsColSize[i], nums, numsSize, k)) { k += groupsColSize[i]; i++; } else { k++; } } return i == groupsSize; }
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; }
classSolution { public: intfind(vector<int> &nums, int k, vector<int> &g){ int m = g.size(), n = nums.size(); if (k + g.size() > nums.size()) { return-1; } vector<int> pi(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; }
boolcanChoose(vector<vector<int>>& groups, vector<int>& nums){ int k = 0; for (int i = 0; i < groups.size(); i++) { k = find(nums, k, groups[i]); if (k == -1) { returnfalse; } k += groups[i].size(); } returntrue; } };
publicclassSolution { publicboolCanChoose(int[][] groups, int[] nums) { int k = 0; for (int i = 0; i < groups.Length; i++) { k = Find(nums, k, groups[i]); if (k == -1) { returnfalse; } k += groups[i].Length; } returntrue; }
publicintFind(int[] nums, int k, int[] g) { int m = g.Length, n = nums.Length; if (k + g.Length > nums.Length) { return-1; } int[] pi = newint[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; } }
intfind(constint *nums, int numsSize, int k, constint *g, int gSize) { int m = gSize, n = numsSize; if (k + m > n) { return-1; } int pi[m]; pi[0] = 0; 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; }
boolcanChoose(int** groups, int groupsSize, int* groupsColSize, int* nums, int numsSize) { int k = 0; for (int i = 0; i < groupsSize; i++) { k = find(nums, numsSize, k, groups[i], groupsColSize[i]); if (k == -1) { returnfalse; } k += groupsColSize[i]; } returntrue; }
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) { returnfalse; } k += groups[i].length; } returntrue; }
constfind = (nums, k, g) => { let m = g.length, n = nums.length; if (k + g.length > nums.length) { return -1; } const pi = newArray(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; };