寫在前面
樓主大三,春招實習。總結一下筆試的錯題。
有錯誤望指正,感激不盡。
問答題
this
指針的綁定
var name = 'global';
var obj = {
name: 'local',
foo: function(){
this.name = 'foo';
}.bind(window)
};
var bar = new obj.foo();
setTimeout(function() {
console.log(window.name);
}, 0);
console.log(bar.name);
var bar3 = bar2 = bar;
bar2.name = 'foo2';
console.log(bar3.name);
結果:‘foo’,‘foo2’.‘global’
ES6
編譯成ES5
將如下ES6代碼編譯成ES5
ES6
class Person {
constructor (name) {
this.name = name;
}
greet () {
console.log(`Hi, my name is ${this.name}`);
}
greetDelay (time) {
setTimeout(() => {
console.log(`Hi, my name is ${this.name}`);
}, time);
}
}
ES5
var Person = (function(){
this.name = name
Person.prototype.greet = function(){
console.log("Hi, my name is" + this.name)
}
Person.prototype.greetDelay = function(time){
var that = this
setTimeout(function(){
cosole.log("Hi, my name is" + that.name)
},time)
}
})()
算法
美團的算法貌似很重視動態規劃,不過都是leetcode的類似題改編的。
斐波那契數列
美團的斐波那契數列使用暴力遞歸會造成棧的移除,所以簡化成下面的寫法。
形如1, 1, 2, 3, 5, 8, 13, 21, 34, 55的數列,後一位是前面兩位相加(斐波那契數列),寫出函數要求找到第 N位是多少,如:fib(3) => 3 , fib(5) => 8, 要求時間複雜度爲O(n)。
let num = readline()
function fabonacci(num){
if(num === 0 ||num === 1 ) return 1
let res = [1,1,2]
for(let i = 3 ;i<=num ;i++){
res[i] = res[i-1] + res[i-2]
}
return res[num]
}
console.log(fabonacci(num))
最少硬幣問題
美團的第二題是動態規劃問題,動態規劃的核心在於將整體問題分解成局部問題進行求解。根據題意找到動態方程dp[i] = Math.mix(dp[i-coin] +1,dp[i])
零錢兌換
近期某商場由於週年慶,開啓了“0元購”活動。活動中,消費者可以通過組合手中的代金券,實現0元購買指定商品。
聰明的小團想要用算法來幫助他快速計算:對於指定價格的商品,使用代金券湊出其價格即可,但所使用的代金券總面額不可超過商品價格。由於代金券數量有限,使用較少的代金券張數則可以實現價值最大化,即最佳優惠。
假設現有100元的商品,而代金券有50元、30元、20元、5元四種,則最佳優惠是兩張50元面額的代金券;而如果現有65元的商品,則最佳優惠是兩張30元代金券以及一張5元代金券。
請你幫助小團使用一段代碼來實現代金券計算。
while(true){
let nums = parseInt(readline())
if(nums === 0 ) break
let coins = readline().split(" ").map(Number).slice(1)
console.log(fn(coins,nums))
}
function fn(coins,nums){
let dp = new Array(nums+1).fill(Infinity)
dp[0] = 0
for(let i = 1;i<=nums;i++){
for(let coin of coins){
if( i >= coin ){
dp[i] = Math.min(dp[i],dp[i-coin]+1)
}
}
}
return dp[nums] === Infinity ? 'Impossible' : dp[nums]
}
最小路徑和
美團的第三題依舊是動態規劃問題。
關鍵還是動態方程dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1]) + grid[i][j]
leetcode原題
給定一個包含非負整數的 M x N 迷宮,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和最小。每次只能向下或者向右移動一步。
let array = readline().split(" ").map(Number)
let row = array[0],col = array[1]
let grid = []
while(line = readline()){
grid.push(line.split(" ").map(Number))
}
function fn(row,col,grid){
let martix = Array.from(new Array(row),()=>new Array(col))
for(let i = 0;i < row;i++){
for(let j = 0;j < col;j++){
if(i === 0 && j ===0 ){
martix[i][j] = grid[i][j]
}else if(i === 0 && j > 0){
martix[i][j] = martix[i][j-1] + grid[i][j]
}else if(i > 0 && j === 0){
martix[i][j] = martix[i-1][j] + grid[i][j]
}else{
martix[i][j] = Math.min(martix[i][j-1],martix[i-1][j])
+ grid[i][j]
}
}
}
return martix[row-1][col-1]
}
console.log(fn(row,col,grid))