有关模拟的算法题型

剑指 Offer 62. 圆圈中最后剩下的数字

该题是著名的约瑟夫环问题,可以使用动态规划来解决,它是有数学规律的。

f(n)可以由f(n-1)推出,

图片转自LeetCode

 我们在第八次与第七次进行分析,在第八次删除掉c以后会从d开始,而在第七次补充上c以后,需要右移m即可与第八次一致,推广出:(f(n-1)+m)%n = f(n),说明约瑟夫环问题只要得知m的值,n值只需要循环进行计算就可以递归得出,因为m有可能大于n,所以会进行求余操作。

必有f(1)=0

code:

/**
 * @param {number} n
 * @param {number} m
 * @return {number}
 */
var lastRemaining = function(n, m) {
    var res = 0;
    for(var i=2;i<=n;i++){
        res = (res + m)%i
    }
    return res;
};

剑指 Offer 29. 顺时针打印矩阵

该题模拟顺时针打印一个二维矩阵,需要考虑的是四个边界对应位置的变化。

我在这里用的是遍历留出顶点。

image.png

图片转自LeetCode

循环的边界条件是顶部大于底部或者左边大于右边。

之后在进行判断是顶部等于底部还是右边等于左边,分情况进行讨论最后中间值的遍历

code:

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
    if(! matrix.length)return [];
    var left = 0,top = 0,right = matrix[0].length-1,bottom = matrix.length-1;
    var res = [];
    while(left<right && top<bottom){
        for(var i=left;i<right;i++){
            res.push(matrix[top][i]);
        }
        for(var i=top;i<bottom;i++){
            res.push(matrix[i][right]);
        }
        for(var i=right;i>left;i--){
            res.push(matrix[bottom][i]);
        }
        for(var i=bottom;i>top;i--){
            res.push(matrix[i][left]);
        }
        left+=1;
        top+=1;
        right-=1;
        bottom-=1;
    }
    if(left==right){
        for(var i=top;i<=bottom;i++){
            res.push(matrix[i][left]);
        }
    }
    else if(top==bottom){
        for(var i=left;i<=right;i++){
            res.push(matrix[top][i]);
        }
    }
    return res;
};

 剑指 Offer 31. 栈的压入、弹出序列

该题要求判断一个栈弹出的序列是否为栈的压入序列的合法情况

就是说白了模拟栈的压入弹出操作。

定义一个辅助栈stack,用于模拟栈的压入以及弹出。定义一个index指针来访问弹出序列进行到的位置,

在我们每一次进行压入操作时,判断指针当前的出栈序列是否对应压入栈操作的数(注意此处需要使用while来进行判断,)如果判断为真则index+1访问出栈序列的下一个,stack.pop()进行出栈。

如果最后结果栈是空栈,则证明出栈序列是合法的。

299. 猜数字游戏

该题是某一天的每日一题,也是运用了模拟的算法思想。

题目给出了两个字符串,要求我们来对应每一位是否猜的正确,以及其他猜测位置不正确但是数字正确。

定义两个a,b来计算结果,定两个数组来对应一下两个字符串中数字出现的次数(这个次数指的是不对应的次数,如果对应则a++),b循环两个数组取每一位的最小值相加(稍微想一下就可以明白,一定是最小的)

code:

/**
 * @param {string} secret
 * @param {string} guess
 * @return {string}
 */
var getHint = function(secret, guess) {
    var l1 = new Array(10).fill(0);
    var l2 = new Array(10).fill(0);
    var a = 0,b = 0;
    for(var i = 0 ;i<secret.length;i++){
        if(secret[i]==guess[i]){
            a+=1; 
            continue;
        }
        l1[secret[i]]+=1;
        l2[guess[i]]+=1;
    }

    for(var i = 0;i<l1.length;i++){
        b+=Math.min(l1[i],l2[i]);
    }
    return a + 'A' + b + 'B'
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值