zoukankan      html  css  js  c++  java
  • 一道手机解锁模式的编程题--JS实现(排列组合算法)

    现有一个 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
    };
    
  • 相关阅读:
    使用gitblit搭建一个简单的局域网服务器
    Git的一些基本操作和命令
    oracle 常用函数
    Windows 下用 gogs 配置局域网 git server
    慎用 new、delete
    探究functools模块wraps装饰器的用途
    处理QMenu的triggered信号时遇到的一个问题
    浅析MySQL中exists与in的使用
    java-工具类-读取配置文件
    Java web的基本概念
  • 原文地址:https://www.cnblogs.com/arduka/p/12846180.html
Copyright © 2011-2022 走看看