力扣题目
解题思路
java代码
力扣题目:
给定整数 n
和 k
,返回 [1, n]
中字典序第 k
小的数字。
示例 1:
输入: n = 13, k = 2 输出: 10 解释: 字典序的排列是 [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],所以第二小的数字是 10。
示例 2:
输入: n = 1, k = 1 输出: 1
解题思路:
算法原理:
这道题通过逐步试探的方法在按字典序排列的数字序列中找到第 k
个数字。
思路:
- 从数字
1
开始,计算以当前数字curr
为前缀能构成的数字个数steps
。 - 如果
steps
小于k
,说明第k
个数字不在以curr
为前缀的数字中,将curr
增加1
,并减少k
的值。 - 如果
steps
大于等于k
,说明第k
个数字在以curr
为前缀的数字中,将curr
乘以10
,继续在这个前缀下寻找,同时减少k
的值。
代码分析:
findKthNumber
方法中,通过一个循环不断调整curr
的值来逼近第k
个数字。getSteps
方法用于计算以给定数字curr
为前缀能构成的数字个数。
时间复杂度:
平均情况下,时间复杂度为 ,因为每次调整
curr
时,计算前缀的数字个数也需要一定的时间。
空间复杂度:
空间复杂度为 ,只使用了固定的几个变量,空间开销恒定。
java代码:
package org.example;
public class Leetcode440 {
public static void main(String[] args) {
System.out.println(new Leetcode440().findKthNumber(13, 2));
}
public int findKthNumber(int n, int k) {
int curr = 1;
k--;
while (k > 0) {
int steps = getSteps(curr, n);
if (steps <= k) {
k -= steps;
curr++;
} else {
curr = curr * 10;
k--;
}
}
return curr;
}
public int getSteps(int curr, long n) {
int steps = 0;
long first = curr;
long last = curr;
while (first <= n) {
steps += Math.min(last, n) - first + 1;
first = first * 10;
last = last * 10 + 9;
}
return steps;
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项