一、题目
给你两个正整数 n 和 k 。
如果正整数 i 满足 n % i == 0 ,那么我们就说正整数 i 是整数 n 的因子。
考虑整数 n 的所有因子,将它们 升序排列 。请你返回第 k 个因子。如果 n 的因子数少于 k ,请你返回 -1 。
示例 1:
输入:n = 12, k = 3
输出:3
解释:因子列表包括 [1, 2, 3, 4, 6, 12],第 3 个因子是 3 。
示例 2:
输入:n = 7, k = 2
输出:7
解释:因子列表包括 [1, 7] ,第 2 个因子是 7 。
示例 3:
输入:n = 4, k = 4
输出:-1
解释:因子列表包括 [1, 2, 4] ,只有 3 个因子,所以我们应该返回 -1 。
提示:
1 <= k <= n <= 1000
进阶:
你可以设计时间复杂度小于 O(n) 的算法来解决此问题吗?
来源:力扣(LeetCode)
链接: https://leetcode.cn/problems/the-kth-factor-of-n
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、代码
1、解法1:
/*
1.直接遍历1~n所有数,判断哪些是n的因子,同时count记录因子的个数,如果是第k个则跳出循环。
2.判断count是否等于k,是则返回因子,不是则返回-1
*/
int kthFactor(int n, int k){
//1.找到所有的因子
//2.升序排列所有因子
int index = 0;
int factor = 0;
for(int i = 1; i < n + 1; i++){
//i是否为n的因子
if(n % i == 0){
index ++;
}
//3.返回第k个因子
if(index >= k){
factor = i;
break;
}
}
if(index > k || factor == 0){
return -1;
}else{
return factor;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
参考其他coder的解法,可以优化一下
/*
可以如果找到则直接在遍历的过程中返回因子,不需要再遍历结束后判断是否是因子
*/
int kthFactor(int n, int k){
//1.找到所有的因子
//2.升序排列所有因子
int index = 0;
for(int i = 1; i < n + 1; i++){
//i是否为n的因子
if(n % i == 0){
index ++;
}
//3.返回第k个因子
if(index == k){
return i;
}
}
//遍历结束,如果没有返回因子,则不存在
return -1;
}
分析:解法1需要遍历1~n,但根据数学规则可知,如果k是n的因子,则必有n/k为n的因子,所以只需要遍历到便可;对于剩余因子,k取到1遍历,n/k即为因子。这样就是2*次计算。
2、解法2:
int kthFactor(int n, int k){
//1.找到所有的因子
//2.升序排列所有因子
int index = 0;
int i = 1;
for(i = 1; i * i <= n; i++){
//i是否为n的因子
if(n % i == 0){
index ++;
}
//3.返回第k个因子
if(index == k){
return i;
}
}
i--;
//i = n/i,则i记录了两次,需要去重一次
if(i * i == n){
i--;
}
//向1遍历因子
for(i; i>=1; i--){
if(n % i == 0){
index++;
}
if(index == k){
return n/i;
}
}
return -1;
}
时间复杂度:O()
空间复杂度:O(1)
三、总结
计算n的因子可以从1~中找因子,当k为n的因子时,n/k也是n的因子。