跳转至

1492. n 的第 k 个因子

题目描述

给你两个正整数 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) 的算法来解决此问题吗?

解法

方法一:暴力枚举

“因子”是指能整除某个数的数。因此,我们只需要从小到大枚举 $[1,2,..n]$,找到所有能整除 $n$ 的数,然后返回第 $k$ 个即可。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。

1
2
3
4
5
6
7
8
class Solution:
    def kthFactor(self, n: int, k: int) -> int:
        for i in range(1, n + 1):
            if n % i == 0:
                k -= 1
                if k == 0:
                    return i
        return -1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution {
    public int kthFactor(int n, int k) {
        for (int i = 1; i <= n; ++i) {
            if (n % i == 0 && (--k == 0)) {
                return i;
            }
        }
        return -1;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
public:
    int kthFactor(int n, int k) {
        for (int i = 1; i <= n; ++i) {
            if (n % i == 0 && (--k == 0)) {
                return i;
            }
        }
        return -1;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func kthFactor(n int, k int) int {
    for i := 1; i <= n; i++ {
        if n%i == 0 {
            k--
            if k == 0 {
                return i
            }
        }
    }
    return -1
}
1
2
3
4
5
6
7
8
function kthFactor(n: number, k: number): number {
    for (let i = 1; i <= n; ++i) {
        if (n % i === 0 && --k === 0) {
            return i;
        }
    }
    return -1;
}

方法二:枚举优化

我们可以发现,如果 $n$ 有一个因子 $x$,那么 $n$ 一定也有一个因子 $n/x$。

因此,我们先需要枚举 $[1,2,...\left \lfloor \sqrt{n} \right \rfloor]$,找到所有能整除 $n$ 的数,如果找到第 $k$ 个因子,那么直接返回即可。如果没有找到第 $k$ 个因子,那么我们再倒序枚举 $[\left \lfloor \sqrt{n} \right \rfloor ,..1]$,找到第 $k$ 个因子即可。

时间复杂度 $O(\sqrt{n})$,空间复杂度 $O(1)$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Solution:
    def kthFactor(self, n: int, k: int) -> int:
        i = 1
        while i * i < n:
            if n % i == 0:
                k -= 1
                if k == 0:
                    return i
            i += 1
        if i * i != n:
            i -= 1
        while i:
            if (n % (n // i)) == 0:
                k -= 1
                if k == 0:
                    return n // i
            i -= 1
        return -1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int kthFactor(int n, int k) {
        int i = 1;
        for (; i < n / i; ++i) {
            if (n % i == 0 && (--k == 0)) {
                return i;
            }
        }
        if (i * i != n) {
            --i;
        }
        for (; i > 0; --i) {
            if (n % (n / i) == 0 && (--k == 0)) {
                return n / i;
            }
        }
        return -1;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
    int kthFactor(int n, int k) {
        int i = 1;
        for (; i < n / i; ++i) {
            if (n % i == 0 && (--k == 0)) {
                return i;
            }
        }
        if (i * i != n) {
            --i;
        }
        for (; i > 0; --i) {
            if (n % (n / i) == 0 && (--k == 0)) {
                return n / i;
            }
        }
        return -1;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func kthFactor(n int, k int) int {
    i := 1
    for ; i < n/i; i++ {
        if n%i == 0 {
            k--
            if k == 0 {
                return i
            }
        }
    }
    if i*i != n {
        i--
    }
    for ; i > 0; i-- {
        if n%(n/i) == 0 {
            k--
            if k == 0 {
                return n / i
            }
        }
    }
    return -1
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
function kthFactor(n: number, k: number): number {
    let i: number = 1;
    for (; i < n / i; ++i) {
        if (n % i === 0 && --k === 0) {
            return i;
        }
    }
    if (i * i !== n) {
        --i;
    }
    for (; i > 0; --i) {
        if (n % Math.floor(n / i) === 0 && --k === 0) {
            return Math.floor(n / i);
        }
    }
    return -1;
}

评论