Leetcode 1237. Find Positive Integer Solution for a Given Equation

Problem Explanation

This problem is a searching problem that requires to find all pairs (x, y) that fulfill a certain condition set by a function and a target value.

We are provided with a function definition f(x, y), and a target value z. The task is to find all pairs of the x, y whose return value from the function matches z. The function will always be a positive integer function and the x, y that fulfill the condition are guaranteed to be in the range of 1 to 1000. The function also demonstrates an increasing characteristic (f(x, y) < f(x + 1, y) and f(x, y) < f(x, y + 1)).


Let's say we are given a function f(x, y) = x * y and a target value of 6. The pairs that satisfy the condition f(x, y) = 6 would be {(1,6), (2,3), (3,2), (6,1)} because these are the pairs where the result of the function matches the target.

Approach to the Solution

The solution works by using a two-pointer technique which is an efficient algorithm for searching for a pair in a sorted array.

Initially, we set one pointer x at the start of the range (1), and the other pointer y at the end of the range (1000). Next, we loop while x is less than or equal to 1000 and y is greater than or equal to 1, to make sure we stay within the valid range.

Inside the loop, we calculate a result by calling the provided function with the current x and y values.

  1. If result is less than z, we need to increase the x to get a bigger output from the function, because of the increasing property of the function.
  2. If result is more than z, we need to decrease y to get a smaller output from the function.
  3. If result equals z, it means we found a valid pair, then we add the pair into the solution set and move both pointers (increase x and decrease y) for the next possible pair.

This process will loop until we have exhausted all possible pairs.



3class Solution:
4   def findSolution(self, customfunction: 'CustomFunction', z: int) -> List[List[int]]:
5      res = []
6      x = 1
7      y = 1000
8      while x <= 1000 and y >= 1:
9         # call the function with current x and y
10         f = customfunction.f(x, y)
11         if f < z:
12            # increase x to get bigger output
13            x += 1
14         elif f > z:
15            # decrease y to get smaller output
16            y -= 1
17         else:
18            res.append([x, y])
19            # move both pointers
20            x += 1
21            y -= 1
22      return res


3public class Solution {
4    public List<List<Integer>> findSolution(CustomFunction customFunction, int z) {
5        List<List<Integer>> ans = new ArrayList<>();
6        int x = 1;
7        int y = 1000;
9        while (x <= 1000 && y >= 1) {
10            int f = customFunction.f(x, y);
11            if (f < z)
12                ++x;
13            else if (f > z)
14                --y;
15            else
16                ans.add(Arrays.asList(x++, y--));
17        }
19        return ans;
20    }


3var findSolution = function(customfunction, z) {
4    const ans = [];
5    let x = 1;
6    let y = 1000;
8    while (x <= 1000 && y >= 1) {
9        const f = customfunction.f(x, y);
10        if (f < z)
11            ++x;
12        else if (f > z)
13            --y;
14        else
15            ans.push([x++, y--]);
16    }
18    return ans;


3class Solution {
5    vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
6        vector<vector<int>> ans;
7        int x = 1;
8        int y = 1000;
10        while (x <= 1000 && y >= 1) {
11            int f = customfunction.f(x, y);
12            if (f < z)
13                ++x;
14            else if (f > z)
15                --y;
16            else
17                ans.push_back({x++, y--});
18        }
20        return ans;
21    }


3public class Solution {
4    public IList<IList<int>> FindSolution(CustomFunction customfunction, int z) {
5        List<IList<int>> res = new List<IList<int>>();
6        int x = 1, y = 1000;
8        while(x <= 1000 && y > 0) {
9            int val = customfunction.f(x, y);
10            if(val > z) y--;
11            else if(val < z) x++;
12            else res.Add(new List<int>{ x++, y-- });
13        }
15        return res;
16    }

Time and Space Complexity Analysis

Since we are only looping through a fixed range of values (1000), the time complexity of this solution is constant, O(1). Note that the time complexity can only be considered constant because the problem states that x and y are within a fixed range from 1 and 1000. If this range is not specified and could potentially be much larger, the time complexity would not be constant.

In terms of space complexity, the solution uses a single, constant amount of space to store the x and y pointers and the results list res regardless of the dataset, therefore, the space complexity is also O(1).

Overall, this is a highly efficient solution as it requires only a constant amount of time and space to solve the problem. It doesn't scale linearly with the input size (which is capped at 1000 in given problem) and doesn't require any large intermediary data structures that can take up considerable space.

For solving such problems, it is crucial to understand the properties of the given function and utilize problem-specific characteristics to optimize the solution, instead of using a brute-force method. In this problem, leveraging the increasing characteristics of the function allows us to apply a more efficient algorithm like two-pointer, resulting in constant time and space complexity.

The simplicity of Python, JavaScript, Java, C++ and C# implementations also helps ensure the solution is understandable and maintainable. The single while loop and the grouping of input parameter modifications offer high readability, allowing for future modifications or extensions if required.

Note: The actual time and space complexity may vary based on the specifics of the custom function f(x, y) given. This complexity analysis assumes the basic structure given in the problem statement.

Test Your Solution

For verifying the correctness and efficiency of the above solutions, you can use the below common edge cases:

  • The function f(x, y) equals to x * y and the target number z equals to 6. The solution should be [[1,6],[2,3],[3,2],[6,1]].
  • The function f(x, y) equals to x + y and the target number z equals to 5. The solution should be [[1,4],[2,3],[3,2],[4,1]].
  • The function f(x, y) equals to x * y and the target number z equals to 1000. The solution should be [[1,1000],[2,500],[4,250],[5,200],[8,125],[10,100],[20,50],[25,40],[40,25],[50,20],[100,10],[125,8],[200,5],[250,4],[500,2],[1000,1]]. The solution checks your implementation can handle the largest possible range.

You can also create your custom function and corresponding target number to test the algorithm. Remember, according to the problem's constraints "f(x, y) will always be an increasing function and x, y will always be in the range [1, 1000]".

Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.

TA 👨‍🏫