该题是著名的约瑟夫环问题,可以使用动态规划来解决,它是有数学规律的。
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;
};
该题模拟顺时针打印一个二维矩阵,需要考虑的是四个边界对应位置的变化。
我在这里用的是遍历留出顶点。
图片转自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;
};
该题要求判断一个栈弹出的序列是否为栈的压入序列的合法情况
就是说白了模拟栈的压入弹出操作。
定义一个辅助栈stack,用于模拟栈的压入以及弹出。定义一个index指针来访问弹出序列进行到的位置,
在我们每一次进行压入操作时,判断指针当前的出栈序列是否对应压入栈操作的数(注意此处需要使用while来进行判断,)如果判断为真则index+1访问出栈序列的下一个,stack.pop()进行出栈。
如果最后结果栈是空栈,则证明出栈序列是合法的。
该题是某一天的每日一题,也是运用了模拟的算法思想。
题目给出了两个字符串,要求我们来对应每一位是否猜的正确,以及其他猜测位置不正确但是数字正确。
定义两个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'
};