劍指offer第32題JS演算法:輸入一個整數n,求從1到n這n個整數的十進位制表示中1出現的次數。例如輸入12,從1到12這些整數中包含1的數字有1,10,11和12,1一共出現了5次
阿新 • • 發佈:2018-12-14
題目:輸入一個整數n,求從1到n這n個整數的十進位制表示中1出現的次數。例如輸入12,從1到12這些整數中包含1的數字有1,10,11和12,1一共出現了5次
這是我某一次去朋友公司面試試水時出的面試題,結果給我五分鐘我寫了個for迴圈的方法,被狠狠鄙視/哭笑不得
結果回來後好奇就跟同事一起看了看這道題發現也挺有意思的
//引數n為中點數字,且為整數 function result(n){ //count表示觀察的值(這裡為1)出現的次數,base表示當前迴圈權重,round表示當前要進入迴圈的數和當前數的週期(高位) let count = 0,base = 1,round = n //當前要進入迴圈的數不小於1時,執行迴圈 while(round>=1){ //求出當前數基數 let weight = round % 10 //求出當前數週期(向下取整),並用作下一輪迴圈的數 round = Math.floor(round / 10) //當基數小於1(即為0)時,出現次數為當前週期乘以當前權重 if(weight < 1){ count += round * base //當基數大於1時,出現次數為當前週期乘以當前權重再加上額外的一次權重 }else if(weight > 1){ count += (round + 1) * base //當基數等於1時,出現次數為當前週期乘以當前權重再加上(基數低一位的數值加1,加1是因為從0開始計數) } else if(weight === 1){ count += round * base + (n%base)+1 } //本次迴圈完畢後權重乘以10,實現按位數迴圈,達到O(logn)的複雜度 base *= 10 } //返回最終的出現總次數 return count }
改良版: function result(n,m){ let count = 0,base = 1,round = n while(round>=m){ let weight = round % 10 round = Math.floor(round / 10) if(weight > m){ count += (round + 1) * base } else if(weight === m){ count += round * base + (n%base)+1 } else{ count += round * base } base *= 10 } return count } n為最大整數,m為要觀察次數的數字