给你一个整数数组 digits ,其中每个元素是一个数字(0 - 9)。数组中可能存在重复元素。
你需要找出 所有 满足下述条件且 互不相同 的整数:
- 该整数由
digits中的三个元素按 任意 顺序 依次连接 组成。 - 该整数不含 前导零
- 该整数是一个 偶数
例如,给定的 digits 是 [1, 2, 3] ,整数 132 和 312 满足上面列出的全部条件。
将找出的所有互不相同的整数按 递增顺序 排列,并以数组形式返回 。
示例 1:
输入: digits = [2,1,3,0]
输出: [102,120,130,132,210,230,302,310,312,320]
解释:
所有满足题目条件的整数都在输出数组中列出。
注意,答案数组中不含有 奇数 或带 前导零 的整数。
示例 2:
输入: digits = [2,2,8,8,2]
输出: [222,228,282,288,822,828,882]
解释:
同样的数字(0 - 9)在构造整数时可以重复多次,重复次数最多与其在 digits 中出现的次数一样。
在这个例子中,数字 8 在构造 288、828 和 882 时都重复了两次。
示例 3:
输入: digits = [3,7,5]
输出: []
解释:
使用给定的 digits 无法构造偶数。
巧妙地跳过循环
/*
https://leetcode.cn/u/cshappyeveryday/
执行用时:70 ms, 在所有 Typescript 提交中击败了87.50%的用户
内存消耗:52.86 MB, 在所有 Typescript 提交中击败了100.00%的用户
时间复杂度:O(n^3)
2024年8月27日
*/
function findEvenNumbers(digits: number[]): number[] {
const ans = new Set<number>();
// 百分位,100-900,如果已经出现过其中一个数了,则再次出现时不用计算
const usedL = new Set<number>();
// 百分位+十分位,100-990,如果已经出现过其中一个数了,则再次出现时不用计算
const usedLM = new Set<number>();
const n = digits.length;
for (let l = 0; l < n; l++) {
const lv = digits[l] * 100;
// 已经计算过的则跳过
if (lv === 0 || usedL.has(lv)) continue;
usedL.add(lv);
for (let m = 0; m < n; m++) {
const lmv = lv + digits[m] * 10;
// 已经计算过的则跳过,并且和百分位的索引要不相同
if (m === l || usedLM.has(lmv)) continue;
usedLM.add(lmv);
for (let r = 0; r < n; r++) {
//和百分位、十分位的索引要不相同
if (r === l || r === m || digits[r] % 2 !== 0) continue;
const v = lmv + digits[r];
ans.add(v);
}
}
}
return [...ans.values()].sort((a, b) => a - b);
}