现有一个 3x3 规格的智能手机锁屏程序和两个正整数 m 和 n ,请计算出使用最少m 个键和最多 n个键可以解锁该屏幕的所有有效模式总数。
其中有效模式是指:
1、每个模式必须连接至少m个键和最多n个键;
2、所有的键都必须是不同的;
3、如果在模式中连接两个连续键的行通过任何其他键,则其他键必须在模式中选择,不允许跳过非选择键(如图);
4、顺序相关,单键有效(这里可能跟部分手机不同)。
输入:m,n
代表允许解锁的最少m个键和最多n个键
输出:
满足m和n个键数的所有有效模式的总数
题目原链接
解题思路
1、先要从9个键中选出x个键,且顺序相关,我们自然想到这是一个排列问题,若不考虑条件3,则选择x个键,模式有“Ax9”个(1<=x && x<=9)
2、条件3规定不允许跳过中间键,则这种特殊情况要剔除。比方说:若x=4,排列方式之一有“1324”即为不合法,“2134”为合法,因为2在1,3之间,若2排列在前,“13”可相邻,若2未选中或排列在其后,则1,3不可相邻
JavaScript实现如下:
/**
* 实现方案
* @param m int整型 最少m个键
* @param n int整型 最多n个键
* @return int整型
*/
function solution( m , n ) {
// write code here
//求从array中选出k个元素的排列函数
function permute(array, k) {
let res = [];
if (k <= 0) {
return res;
}
function generatePermutation(array, index, p) {
if (index == k) {
res.push(p.join(''));
return;
}
for (let i of array) {
if (p.indexOf(i) == -1) {
p.push(i);
generatePermutation(array, index + 1, p);
p.pop();
}
}
}
generatePermutation(array, 0, []);
return res;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var res = []; //此数组容纳“[n,m]”范围内的所有排列
let maxNum = n > arr.length ? arr.length : n;
for (let i = m; i <= maxNum; i++) {
res = res.concat(permute(arr, i));
}
//特殊情况下的跨点路径
imp = [
['13', '2'],
['17', '4'],
['19', '5'],
['28', '5'],
['31', '2'],
['37', '5'],
['39', '6'],
['46', '5'],
['64', '5'],
['71', '4'],
['73', '5'],
['79', '8'],
['82', '5'],
['91', '5'],
['93', '6'],
['97', '8']
];
const map = new Map(imp);
var count = res.length;
for (let i of res) {
for (let [k, v] of map) {
let kIndex = i.indexOf(k);
let vIndex = i.indexOf(v);
if (kIndex != -1 && (vIndex > kIndex || vIndex == -1)) {
count--;
break;
}
}
}
return count;
}
module.exports = {
solution : solution
};