Facebook Pixel

1492. The kth Factor of n

MediumMathNumber Theory
Leetcode Link

Problem Description

You need to find the k-th smallest factor of a positive integer n.

A factor of n is any integer i where n is divisible by i (meaning n % i == 0). For example, the factors of 12 are: 1, 2, 3, 4, 6, and 12.

Given two positive integers:

  • n: the number whose factors you need to find
  • k: the position of the factor you want (1st, 2nd, 3rd, etc.)

Your task is to:

  1. Find all factors of n
  2. Sort them in ascending order (smallest to largest)
  3. Return the k-th factor from this sorted list

If n has fewer than k factors, return -1.

Example walkthrough:

  • If n = 12 and k = 3
  • The factors of 12 in ascending order are: [1, 2, 3, 4, 6, 12]
  • The 3rd factor is 3
  • Return 3

The solution iterates through all numbers from 1 to n, checking if each number divides n evenly. It counts each factor found and returns the k-th one when reached. If after checking all numbers from 1 to n, fewer than k factors were found, it returns -1.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The most straightforward way to find the k-th factor is to check every possible number that could be a factor. Since a factor must divide n evenly, we need to test each number from 1 to n to see if it divides n without a remainder.

Why start from 1 and go up to n? Because:

  • 1 is always a factor of any positive integer
  • n itself is always a factor of n
  • All other factors must lie between these two values

As we iterate through numbers from 1 to n, we can use a counter to keep track of how many factors we've found so far. Each time we find a number i where n % i == 0, we know it's a factor, so we decrement our counter k. When k reaches 0, we've found exactly k factors, and the current number is our answer.

The beauty of iterating from 1 upward is that we naturally encounter factors in ascending order. We don't need to store all factors in a list and then sort them - the sequential checking gives us the sorted order automatically.

If we complete the entire loop from 1 to n without k reaching 0, it means n has fewer than k factors, so we return -1.

This approach trades potential efficiency for simplicity and clarity. While we could optimize by only checking up to √n (since factors come in pairs), the brute force method is easier to understand and implement, making it less prone to errors.

Learn more about Math patterns.

Solution Approach

The implementation uses a simple linear search algorithm to find the k-th factor:

Step-by-step implementation:

  1. Iterate through potential factors: Use a for loop to check every integer from 1 to n inclusive:

    for i in range(1, n + 1):
  2. Check if i is a factor: For each number i, test if it divides n evenly using the modulo operator:

    if n % i == 0:

    When n % i == 0, we know that i is a factor of n.

  3. Count the factors: Each time we find a factor, decrement k by 1:

    k -= 1

    This effectively counts down from k to 0, tracking how many more factors we need to find.

  4. Return when k-th factor is found: When k reaches 0, we've found exactly k factors, and the current value of i is our answer:

    if k == 0:
        return i
  5. Handle insufficient factors: If the loop completes without finding k factors (k never reached 0), return -1:

    return -1

Time and Space Complexity:

  • Time Complexity: O(n) - We iterate through all numbers from 1 to n in the worst case
  • Space Complexity: O(1) - We only use a constant amount of extra space for the loop variable and counter

The algorithm doesn't require any additional data structures like arrays or lists to store factors. By processing factors in their natural ascending order and using a countdown mechanism with k, we achieve an elegant solution that directly returns the k-th factor when found.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through finding the 4th smallest factor of n = 20.

Step 1: Initialize

  • n = 20, k = 4
  • We need to find the 4th factor of 20

Step 2: Iterate and check each number

  • i = 1: Is 20 % 1 == 0? Yes! (20 ÷ 1 = 20)

    • Found a factor, k = 4 - 1 = 3
    • k ≠ 0, continue
  • i = 2: Is 20 % 2 == 0? Yes! (20 ÷ 2 = 10)

    • Found a factor, k = 3 - 1 = 2
    • k ≠ 0, continue
  • i = 3: Is 20 % 3 == 0? No (20 ÷ 3 = 6 remainder 2)

    • Not a factor, k stays at 2, continue
  • i = 4: Is 20 % 4 == 0? Yes! (20 ÷ 4 = 5)

    • Found a factor, k = 2 - 1 = 1
    • k ≠ 0, continue
  • i = 5: Is 20 % 5 == 0? Yes! (20 ÷ 5 = 4)

    • Found a factor, k = 1 - 1 = 0
    • k == 0, we found our 4th factor!
    • Return 5

Result: The 4th smallest factor of 20 is 5.

For reference, all factors of 20 are: [1, 2, 4, 5, 10, 20], and indeed the 4th one is 5.

Solution Implementation

1class Solution:
2    def kthFactor(self, n: int, k: int) -> int:
3        """
4        Find the kth factor of n in ascending order.
5      
6        Args:
7            n: The number to find factors of
8            k: The position of the factor to return (1-indexed)
9          
10        Returns:
11            The kth factor of n, or -1 if n has less than k factors
12        """
13        # Iterate through all potential factors from 1 to n
14        for i in range(1, n + 1):
15            # Check if i is a factor of n
16            if n % i == 0:
17                # Decrement k for each factor found
18                k -= 1
19                # If we've found the kth factor, return it
20                if k == 0:
21                    return i
22      
23        # If we've checked all numbers and k > 0, n has fewer than k factors
24        return -1
25
1class Solution {
2    /**
3     * Finds the kth factor of a given number n.
4     * Factors are listed in ascending order.
5     * 
6     * @param n The number to find factors of
7     * @param k The position of the factor to return (1-indexed)
8     * @return The kth factor if it exists, otherwise -1
9     */
10    public int kthFactor(int n, int k) {
11        // Iterate through all potential factors from 1 to n
12        for (int potentialFactor = 1; potentialFactor <= n; potentialFactor++) {
13            // Check if current number is a factor of n
14            if (n % potentialFactor == 0) {
15                // Decrement k and check if we've found the kth factor
16                k--;
17                if (k == 0) {
18                    // Found the kth factor
19                    return potentialFactor;
20                }
21            }
22        }
23      
24        // If k factors don't exist, return -1
25        return -1;
26    }
27}
28
1class Solution {
2public:
3    /**
4     * Find the k-th factor of n in ascending order.
5     * 
6     * @param n: The number to find factors of
7     * @param k: The position of the factor to return (1-indexed)
8     * @return: The k-th factor if it exists, otherwise -1
9     */
10    int kthFactor(int n, int k) {
11        // Iterate through all potential factors from 1 to n
12        for (int factor = 1; factor <= n; ++factor) {
13            // Check if current number is a factor of n
14            if (n % factor == 0) {
15                // Decrement k and check if we've found the k-th factor
16                --k;
17                if (k == 0) {
18                    return factor;
19                }
20            }
21        }
22      
23        // If k factors don't exist, return -1
24        return -1;
25    }
26};
27
1/**
2 * Finds the k-th factor of a given number n
3 * @param n - The number to find factors for
4 * @param k - The position of the factor to return (1-indexed)
5 * @returns The k-th factor of n, or -1 if n has less than k factors
6 */
7function kthFactor(n: number, k: number): number {
8    // Iterate through all potential factors from 1 to n
9    for (let i = 1; i <= n; i++) {
10        // Check if i is a factor of n
11        if (n % i === 0) {
12            // Decrement k and check if we've found the k-th factor
13            k--;
14            if (k === 0) {
15                return i;
16            }
17        }
18    }
19  
20    // If we've exhausted all factors and haven't found the k-th one
21    return -1;
22}
23

Time and Space Complexity

The time complexity is O(n) because the algorithm iterates through all integers from 1 to n in the worst case. In each iteration, it performs a constant-time modulo operation to check if i is a factor of n. The loop runs at most n times, making the overall time complexity linear with respect to n.

The space complexity is O(1) because the algorithm only uses a fixed amount of extra space regardless of the input size. It maintains only a few variables (i for the loop counter and the parameter k which is decremented) that don't grow with the input size n.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Inefficient O(n) Time Complexity for Large Numbers

The current solution always iterates from 1 to n, which becomes extremely slow for large values of n. For example, if n = 1,000,000 and k = 2, the algorithm still checks all million numbers even though the answer is 2.

Better Approach: Optimize by only iterating up to √n, since factors come in pairs:

class Solution:
    def kthFactor(self, n: int, k: int) -> int:
        factors = []
      
        # Find factors up to sqrt(n)
        for i in range(1, int(n**0.5) + 1):
            if n % i == 0:
                factors.append(i)
                if len(factors) == k:
                    return i
      
        # Handle the second half of factors in reverse
        start = len(factors) - 1
        if factors[-1]**2 == n:  # Perfect square case
            start -= 1
          
        for i in range(start, -1, -1):
            k -= 1
            if k == 0:
                return n // factors[i]
      
        return -1

2. Not Handling Edge Cases Properly

The naive implementation doesn't validate inputs, which could lead to unexpected behavior:

  • What if k = 0 or k < 0?
  • What if n = 0 or n < 0?

Solution: Add input validation:

def kthFactor(self, n: int, k: int) -> int:
    if n <= 0 or k <= 0:
        return -1
    # Rest of the implementation

3. Memory Usage When Only One Factor is Needed

Some developers might instinctively collect all factors first, then return the k-th one:

# Inefficient approach - don't do this!
def kthFactor(self, n: int, k: int) -> int:
    factors = []
    for i in range(1, n + 1):
        if n % i == 0:
            factors.append(i)
  
    return factors[k-1] if k <= len(factors) else -1

This uses O(d) space where d is the number of divisors, which is unnecessary when we only need one specific factor.

4. Integer Overflow in Other Languages

While Python handles arbitrary-precision integers automatically, implementing this in languages like C++ or Java requires careful consideration of integer overflow when dealing with large values of n.

5. Off-by-One Errors with k

Developers might confuse whether k is 0-indexed or 1-indexed. The problem specifies k is 1-indexed (k=1 means the first factor), but it's easy to make mistakes when decrementing k or accessing array indices.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

How many ways can you arrange the three letters A, B and C?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More