JavaScript|LeetCode|动态规划/递归|650. 只有两个键的键盘

本文介绍了如何使用动态规划和递归方法解决LeetCode第650题,即在只有两个键的键盘上打印出指定数量的'A'字符的最小操作次数。动态规划策略通过维护一个数组dp来更新最少操作次数,而递归策略则根据数字是否为质数来确定操作次数。两种方法都详细阐述了思路和公式推导。

法1:动态规划
想法:

  1. copy all 算 1 次操作;paste 算 1 次操作
  2. 数组 dp:dp[i] 表示打印出 i 个 ‘A’ 的最少操作次数。
  • 从前向后更新 dp :找 i % j == 0 中,j 的最大值(n >= i > j >= 1)
  • dp[i] = dp[j] + 1 + (i / j - 1)
    dp[j]表示得到 j 个 A 所需的最少操作次数;1 表示 copy 这 j 个 A,(i / j - 1) 表示 paste 的次数(本身已经存在一份 j 个 A,故减去 1 次)
  • 整理上式:dp[i] = dp[j] + i / j
  1. 返回dp[n]
/** 
* @param {number} n 
* @return {number} 
*/
var minSteps = function(n) {    
    // copy all算 1 次操作;paste算 1 次操作    
    // 数组dp    
    // 从前向后更新:找 i % j == 0 中,j 的最大值(n >= i > j >= 1)    
    // 返回dp[n]    
    var dp = [], i = 0, j = 0    
    for(i = 0; i <= n; i++) {        
        dp[i] = 0;    
    }
    for(i = 2; i <= n; i++) {
        // 可以如此:j = Math.floor(i / 2),效率会更高        
        for(j = i - 1; j >= 1; j--) {            
            if(i % j == 0) {                
                // 1: copy; (i / j - 1): paste                
                // dp[i] = dp[j] + 1 + (i / j - 1);                 
                dp[i] = dp[j] + i / j;                
                break;            
            }        
        }    
    }    
    return dp[n];
};

法2:递归
看了题解
想法:

  1. 对于n:
  • 如果 n 是素数,则只能由 1 个 A 经过多次 paste 得到,答案为 1 + n - 1 = n(copy 1 次,paste n - 1次)
  • 如果 n 不是素数,则找到 n 的最大约数 i ,并求得到 i 个 A 的最少操作数 minSteps(i);答案为:minSteps(i) + 1 + n / i - 1 = minSteps(i) + n / i
/** 
* @param {number} n 
* @return {number} 
*/
var minSteps = function(n) {    
    if(n == 1) {        
        return 0;    
    }    
    var i = 0;    
    for(i = Math.floor(n / 2); i >= 2; i--) {        
        if(n % i == 0) { // i 是 n 的约数,n 不是素数            
            return minSteps(i) + n / i;        
        }    
    }    
    return n;
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值