在我的解决方案中,我们不需要大量的迭代和循环...但是这个解决方案对于简单理解来说很大...
我为6位数字制作了它,它非常高效...并且可以制作任意数量的数字...甚至可以缩小到小函数,但那样会变得太复杂而难以理解...
所以,给定数字的总数:
对于1位数字,它们是10(0到9)....
对于2位数字,它们是9*10 => 90,总数字 => 90*2 => 180...
对于3位数字,它们是9*10*10 => 900,总数字 => 90*3 => 2700...
对于4位数字,它们是9*10*10*10 => 9000,总数字 => 9000*4 => 36000...
一个用于获取指定位数的总数字的函数。
let totalDigits = n => {
if (n == 1) return 10;
return 9 * (10 ** (n - 1)) * n;
}
现在,我们为不同的数字设置一个位置范围,
对于1位数字,它在1到10之间....
对于2位数字,它在11(1 + 10)和190(180 + 10)之间......(10中的1的位置是11,99中第二个9的位置是190)...
对于3位数字,它在191(1 + 10 + 180)和2890(2700 + 180 + 10)之间......以此类推
对于n位数字,获取范围的函数为
// This function is used to find Range for Positions... Eg : 2 digit Numbers are upto Position 190...(Position 191 is "100" first digit => 1 )
let digitN = n => {
if (n == 1) return totalDigits(1);
return digitN(n - 1) + totalDigits(n);
}
// To Finally set Ranege for a Given Digit Number... for 1 its [1,10] , for 2 its [11,190]
let positionRange = n => {
if (n == 1) return [1, 10];
else return [digitN(n - 1), digitN(n)]
}
所以最终解决方案是
// This Function tells the total number of digits for the given digit... Eg : there are 10 one digit Numbers , 180 Two Digit Numbers , 2700 3 Digit Numbers
let totalDigits = n => {
if (n == 1) return 10;
return 9 * (10 ** (n - 1)) * n;
}
// This function is used to find Range for Positions... Eg : 2 digit Numbers are upto Position 190...(Position 191 is "100" first digit => 1 )
let digitN = n => {
if (n == 1) return totalDigits(1);
return digitN(n - 1) + totalDigits(n);
}
// To Finally set Ranege for a Given Digit Number... for 1 its [1,10] , for 2 its [11,190]
let positionRange = n => {
if (n == 1) return [1, 10];
else return [digitN(n - 1), digitN(n)]
}
// A simple Hack to get same value for Different Consecutive Numbers , (0.3 or 0.6 or 0.9 or 1 return 1)
let getDigit = n => {
if (dataType(n) == "float") {
n = Math.floor(n);
n++;
}
return n;
}
// To check for Float or Integer Values
function dataType(x) {
if (Math.round(x) === x) {
return 'integer';
}
return 'float';
}
function f(position) {
let result, charInd, temp;
if ((position >= positionRange(1)[0]) && (position <= positionRange(1)[1])) { // Positions 1 to 10 (1 Digit Numbers)
result = position - 1;
charInd = 0
}
if ((position > positionRange(2)[0]) && (position <= positionRange(2)[1])) { // Positions 11 to 190 (2 Digit Numbers)
temp = (position - 10) / 2;
temp = getDigit(temp);
result = temp + 9;
charInd = (position - 11) % 2
}
if ((position > positionRange(3)[0]) && (position <= positionRange(3)[1])) { // Positions 191 to 2890 (3 Digit Numbers)
temp = (position - 190) / 3;
temp = getDigit(temp);
result = temp + 99;
charInd = (position - 191) % 3
}
if ((position > positionRange(4)[0]) && (position <= positionRange(4)[1])) { // Positions 2891 to 38890 (4 Digit Numbers)
temp = (position - 2890) / 4;
temp = getDigit(temp);
result = temp + 999;
charInd = (position - 2891) % 4
}
if ((position > positionRange(5)[0]) && (position <= positionRange(5)[1])) { // Positions 38890 to 488890 (5 Digit Numbers)
temp = (position - 38890) / 5;
temp = getDigit(temp);
result = temp + 9999;
charInd = (position - 38891) % 5
}
if ((position > positionRange(6)[0]) && (position <= positionRange(6)[1])) { // Positions 488890 to 5888890 (6 Digit Numbers)
temp = (position - 488890) / 6 ;
temp = getDigit(temp);
result = temp + 99999;
charInd = (position - 488891) % 6
}
finalChar = String(result)[charInd];
console.log("Given Position => ", position, " Result Number => ", result, "Char Index ==> ", charInd, "Final Char => ", finalChar);
}
let d1 = Date.now();
f(138971); // Given Position => 138971 Result Number => 30016 Char Index ==> 0 Final Char => 3
let d2 = Date.now();
console.log(d2-d1) ; // 351
currentNumber ++;
从0到所需的位数。它可能可以工作,但就像帖子作者的实现一样,它不是一个非常高效的算法(只是现代计算机可以执行1e9个操作)。 - CertainPerformanceO(n)
,但对于作者要求的10^9范围的输入,它在1秒内运行。然而,我同意在时间上更有效的解决方案是在这里使用数学,就像你的答案中所做的那样。 - Ajay Dabas