如何减少从连续数字中找到第 n 个位置的时间少于 1 秒
How to reduce time to find the n-th place from consecutive digits number for less than 1 second
我正在跟编程测试,有这样的问题
From this consecutive digits:
123456789101112131415161718192021....
For example The 10th digit is 1 The 11th digit is 0 and so on
What is the 1,000,000th digit?
What is the 1,000,000,000th digit?
What is the 1,000,000,000,000th digit?
Your solution should run below 1 second.
我已经回答了,但仍然超过 1 秒。我尝试使用多项式。
那么,如何减少从上面的数字中找到第 n 个位置的时间?
这是我的回答,(PHP):
function digit_pol ($n) {
$counter = 1;
$digit_arr = array();
for ($i = 1; $i <= $n; $i++) {
for ($j = 0; $j < strlen($i); $j++) {
// If array more than 100, always shift (limit array length to 11)
if($i > 10) {
array_shift($digit_arr);
}
// Fill array
$digit_arr[$counter] = substr($i, $j, 1);
// Found
if($counter == $n) {
return $digit_arr[$counter];
}
$counter++;
}
}
}
/**
* TESTING
*/
$find_place = 1000000;
$result = digit_pol($find_place);
echo "Digit of " . $find_place . "th is <b>" . $result . "</b>";
重要的是要认识到迈出大步很容易:
1 digit numbers: 123456789 - 9 * 1 digit
2 digit numbers: 101112...9899 - 90 * 2 digits
3 digit numbers: 100101102...998999 - 900 * 3 digits
4 digit numbers: ...
现在你可以做一个递归求解,跳过9×10k×k 数字,直到达到基本情况,其中 n
在当前幅度的数字范围内。
如果您知道要查找的特定范围,就很容易找到第 n
个数字。先把n
除以每个数的长度。这会将 数字偏移量 转换为 数字偏移量 。现在向其中添加 10k 以获得要查看的实际数字。在这一点上,这是在给定数字中找到特定数字的问题.
以n = 1234
为例:
n > 9
,所以不在个位数范围内:
- 跳过个位数范围(即
n -= 9
)并继续使用 2 位数...
n > 90 * 2
所以也不在两位数范围内
- 跳过 2 位数范围(即
n -= 90*2
)并继续 3 位数...
- 现在
n < 900 * 3
所以我们要在 100101102...
序列中寻找一个数字
- 由于这个序列中的每个数字都是 3 位数字,我们可以通过
100 + n / 3
找到要查找的特定数字。在这种情况下,这等于 448
.
- 我们现在只需计算
n % 3
(在本例中等于 1
)来找出要选择的数字。因此,最终结果是 4
.
这是 Java 中的解决方案:
public static char nthDigit(int n, int digitsInFirstNum) {
int magnitude = (int) Math.pow(10, digitsInFirstNum - 1);
int digitsInMagnitude = 9 * magnitude * digitsInFirstNum;
if (n < digitsInMagnitude) {
int number = magnitude + n / digitsInFirstNum;
int digitPos = n % digitsInFirstNum;
return String.valueOf(number).charAt(digitPos);
}
return nthDigit(n - digitsInMagnitude, digitsInFirstNum + 1);
}
public static char nthDigit(int n) {
return nthDigit(n, 1);
}
我正在跟编程测试,有这样的问题
From this consecutive digits:
123456789101112131415161718192021....
For example The 10th digit is 1 The 11th digit is 0 and so on
What is the 1,000,000th digit?
What is the 1,000,000,000th digit?
What is the 1,000,000,000,000th digit?
Your solution should run below 1 second.
我已经回答了,但仍然超过 1 秒。我尝试使用多项式。
那么,如何减少从上面的数字中找到第 n 个位置的时间?
这是我的回答,(PHP):
function digit_pol ($n) {
$counter = 1;
$digit_arr = array();
for ($i = 1; $i <= $n; $i++) {
for ($j = 0; $j < strlen($i); $j++) {
// If array more than 100, always shift (limit array length to 11)
if($i > 10) {
array_shift($digit_arr);
}
// Fill array
$digit_arr[$counter] = substr($i, $j, 1);
// Found
if($counter == $n) {
return $digit_arr[$counter];
}
$counter++;
}
}
}
/**
* TESTING
*/
$find_place = 1000000;
$result = digit_pol($find_place);
echo "Digit of " . $find_place . "th is <b>" . $result . "</b>";
重要的是要认识到迈出大步很容易:
1 digit numbers: 123456789 - 9 * 1 digit
2 digit numbers: 101112...9899 - 90 * 2 digits
3 digit numbers: 100101102...998999 - 900 * 3 digits
4 digit numbers: ...
现在你可以做一个递归求解,跳过9×10k×k 数字,直到达到基本情况,其中 n
在当前幅度的数字范围内。
如果您知道要查找的特定范围,就很容易找到第 n
个数字。先把n
除以每个数的长度。这会将 数字偏移量 转换为 数字偏移量 。现在向其中添加 10k 以获得要查看的实际数字。在这一点上,这是在给定数字中找到特定数字的问题.
以n = 1234
为例:
n > 9
,所以不在个位数范围内:- 跳过个位数范围(即
n -= 9
)并继续使用 2 位数...
- 跳过个位数范围(即
n > 90 * 2
所以也不在两位数范围内- 跳过 2 位数范围(即
n -= 90*2
)并继续 3 位数...
- 跳过 2 位数范围(即
- 现在
n < 900 * 3
所以我们要在100101102...
序列中寻找一个数字 - 由于这个序列中的每个数字都是 3 位数字,我们可以通过
100 + n / 3
找到要查找的特定数字。在这种情况下,这等于448
. - 我们现在只需计算
n % 3
(在本例中等于1
)来找出要选择的数字。因此,最终结果是4
.
这是 Java 中的解决方案:
public static char nthDigit(int n, int digitsInFirstNum) {
int magnitude = (int) Math.pow(10, digitsInFirstNum - 1);
int digitsInMagnitude = 9 * magnitude * digitsInFirstNum;
if (n < digitsInMagnitude) {
int number = magnitude + n / digitsInFirstNum;
int digitPos = n % digitsInFirstNum;
return String.valueOf(number).charAt(digitPos);
}
return nthDigit(n - digitsInMagnitude, digitsInFirstNum + 1);
}
public static char nthDigit(int n) {
return nthDigit(n, 1);
}