返回介绍

solution / 1200-1299 / 1237.Find Positive Integer Solution for a Given Equation / README

发布于 2024-06-17 01:03:21 字数 10926 浏览 0 评论 0 收藏 0

1237. 找出给定方程的正整数解

English Version

题目描述

给你一个函数  f(x, y) 和一个目标结果 z,函数公式未知,请你计算方程 f(x,y) == z 所有可能的正整数 数对 xy。满足条件的结果数对可以按任意顺序返回。

尽管函数的具体式子未知,但它是单调递增函数,也就是说:

  • f(x, y) < f(x + 1, y)
  • f(x, y) < f(x, y + 1)

函数接口定义如下:

interface CustomFunction {
public:
  // Returns some positive integer f(x, y) for two positive integers x and y based on a formula.
  int f(int x, int y);
};

你的解决方案将按如下规则进行评判:

  • 判题程序有一个由 CustomFunction9 种实现组成的列表,以及一种为特定的 z 生成所有有效数对的答案的方法。
  • 判题程序接受两个输入:function_id(决定使用哪种实现测试你的代码)以及目标结果 z
  • 判题程序将会调用你实现的 findSolution 并将你的结果与答案进行比较。
  • 如果你的结果与答案相符,那么解决方案将被视作正确答案,即 Accepted

 

示例 1:

输入:function_id = 1, z = 5
输出:[[1,4],[2,3],[3,2],[4,1]]
解释:function_id = 1 暗含的函数式子为 f(x, y) = x + y
以下 x 和 y 满足 f(x, y) 等于 5:
x=1, y=4 -> f(1, 4) = 1 + 4 = 5
x=2, y=3 -> f(2, 3) = 2 + 3 = 5
x=3, y=2 -> f(3, 2) = 3 + 2 = 5
x=4, y=1 -> f(4, 1) = 4 + 1 = 5

示例 2:

输入:function_id = 2, z = 5
输出:[[1,5],[5,1]]
解释:function_id = 2 暗含的函数式子为 f(x, y) = x * y
以下 x 和 y 满足 f(x, y) 等于 5:
x=1, y=5 -> f(1, 5) = 1 * 5 = 5
x=5, y=1 -> f(5, 1) = 5 * 1 = 5

 

提示:

  • 1 <= function_id <= 9
  • 1 <= z <= 100
  • 题目保证 f(x, y) == z 的解处于 1 <= x, y <= 1000 的范围内。
  • 1 <= x, y <= 1000 的前提下,题目保证 f(x, y) 是一个 32 位有符号整数。

解法

方法一:枚举 + 二分查找

根据题目我们可以知道,函数 $f(x, y)$ 是单调递增函数,因此,我们可以枚举 $x$,然后在 $[1,…z]$ 中二分查找 $y$,使得 $f(x, y) = z$。如果找到了,就将 $(x, y)$ 加入答案中。

时间复杂度 $(n \log n)$,其中 $n$ 是 $z$ 的值,空间复杂度 $O(1)$。

"""
   This is the custom function interface.
   You should not implement it, or speculate about its implementation
   class CustomFunction:
     # Returns f(x, y) for any given positive integers x and y.
     # Note that f(x, y) is increasing with respect to both x and y.
     # i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
     def f(self, x, y):

"""


class Solution:
  def findSolution(self, customfunction: "CustomFunction", z: int) -> List[List[int]]:
    ans = []
    for x in range(1, z + 1):
      y = 1 + bisect_left(
        range(1, z + 1), z, key=lambda y: customfunction.f(x, y)
      )
      if customfunction.f(x, y) == z:
        ans.append([x, y])
    return ans
/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 *   // Returns f(x, y) for any given positive integers x and y.
 *   // Note that f(x, y) is increasing with respect to both x and y.
 *   // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *   public int f(int x, int y);
 * };
 */

class Solution {
  public List<List<Integer>> findSolution(CustomFunction customfunction, int z) {
    List<List<Integer>> ans = new ArrayList<>();
    for (int x = 1; x <= 1000; ++x) {
      int l = 1, r = 1000;
      while (l < r) {
        int mid = (l + r) >> 1;
        if (customfunction.f(x, mid) >= z) {
          r = mid;
        } else {
          l = mid + 1;
        }
      }
      if (customfunction.f(x, l) == z) {
        ans.add(Arrays.asList(x, l));
      }
    }
    return ans;
  }
}
/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 * public:
 *   // Returns f(x, y) for any given positive integers x and y.
 *   // Note that f(x, y) is increasing with respect to both x and y.
 *   // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *   int f(int x, int y);
 * };
 */

class Solution {
public:
  vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
    vector<vector<int>> ans;
    for (int x = 1; x <= 1000; ++x) {
      int l = 1, r = 1000;
      while (l < r) {
        int mid = (l + r) >> 1;
        if (customfunction.f(x, mid) >= z) {
          r = mid;
        } else {
          l = mid + 1;
        }
      }
      if (customfunction.f(x, l) == z) {
        ans.push_back({x, l});
      }
    }
    return ans;
  }
};
/**
 * This is the declaration of customFunction API.
 * @param  x  int
 * @param  x  int
 * @return     Returns f(x, y) for any given positive integers x and y.
 *        Note that f(x, y) is increasing with respect to both x and y.
 *        i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 */

func findSolution(customFunction func(int, int) int, z int) (ans [][]int) {
  for x := 1; x <= 1000; x++ {
    y := 1 + sort.Search(999, func(y int) bool { return customFunction(x, y+1) >= z })
    if customFunction(x, y) == z {
      ans = append(ans, []int{x, y})
    }
  }
  return
}
/**
 * // This is the CustomFunction's API interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 *    f(x: number, y: number): number {}
 * }
 */

function findSolution(customfunction: CustomFunction, z: number): number[][] {
  const ans: number[][] = [];
  for (let x = 1; x <= 1000; ++x) {
    let l = 1;
    let r = 1000;
    while (l < r) {
      const mid = (l + r) >> 1;
      if (customfunction.f(x, mid) >= z) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    if (customfunction.f(x, l) == z) {
      ans.push([x, l]);
    }
  }
  return ans;
}

方法二:双指针

我们可以定义两个指针 $x$ 和 $y$,初始时 $x = 1$, $y = z$。

  • 如果 $f(x, y) = z$,我们将 $(x, y)$ 加入答案中,然后 $x \leftarrow x + 1$, $y \leftarrow y - 1$;
  • 如果 $f(x, y) \lt z$,此时对任意的 $y' \lt y$,都有 $f(x, y') \lt f(x, y) \lt z$,因此我们不能将 $y$ 减小,只能将 $x$ 增大,所以 $x \leftarrow x + 1$;
  • 如果 $f(x, y) \gt z$,此时对任意的 $x' \gt x$,都有 $f(x', y) \gt f(x, y) \gt z$,因此我们不能将 $x$ 增大,只能将 $y$ 减小,所以 $y \leftarrow y - 1$。

循环结束后,返回答案。

时间复杂度 $O(n)$,其中 $n$ 是 $z$ 的值,空间复杂度 $O(1)$。

"""
   This is the custom function interface.
   You should not implement it, or speculate about its implementation
   class CustomFunction:
     # Returns f(x, y) for any given positive integers x and y.
     # Note that f(x, y) is increasing with respect to both x and y.
     # i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
     def f(self, x, y):

"""


class Solution:
  def findSolution(self, customfunction: "CustomFunction", z: int) -> List[List[int]]:
    ans = []
    x, y = 1, 1000
    while x <= 1000 and y:
      t = customfunction.f(x, y)
      if t < z:
        x += 1
      elif t > z:
        y -= 1
      else:
        ans.append([x, y])
        x, y = x + 1, y - 1
    return ans
/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 *   // Returns f(x, y) for any given positive integers x and y.
 *   // Note that f(x, y) is increasing with respect to both x and y.
 *   // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *   public int f(int x, int y);
 * };
 */

class Solution {
  public List<List<Integer>> findSolution(CustomFunction customfunction, int z) {
    List<List<Integer>> ans = new ArrayList<>();
    int x = 1, y = 1000;
    while (x <= 1000 && y > 0) {
      int t = customfunction.f(x, y);
      if (t < z) {
        x++;
      } else if (t > z) {
        y--;
      } else {
        ans.add(Arrays.asList(x++, y--));
      }
    }
    return ans;
  }
}
/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 * public:
 *   // Returns f(x, y) for any given positive integers x and y.
 *   // Note that f(x, y) is increasing with respect to both x and y.
 *   // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *   int f(int x, int y);
 * };
 */

class Solution {
public:
  vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
    vector<vector<int>> ans;
    int x = 1, y = 1000;
    while (x <= 1000 && y) {
      int t = customfunction.f(x, y);
      if (t < z) {
        x++;
      } else if (t > z) {
        y--;
      } else {
        ans.push_back({x++, y--});
      }
    }
    return ans;
  }
};
/**
 * This is the declaration of customFunction API.
 * @param  x  int
 * @param  x  int
 * @return     Returns f(x, y) for any given positive integers x and y.
 *        Note that f(x, y) is increasing with respect to both x and y.
 *        i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 */

func findSolution(customFunction func(int, int) int, z int) (ans [][]int) {
  x, y := 1, 1000
  for x <= 1000 && y > 0 {
    t := customFunction(x, y)
    if t < z {
      x++
    } else if t > z {
      y--
    } else {
      ans = append(ans, []int{x, y})
      x, y = x+1, y-1
    }
  }
  return
}
/**
 * // This is the CustomFunction's API interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 *    f(x: number, y: number): number {}
 * }
 */

function findSolution(customfunction: CustomFunction, z: number): number[][] {
  let x = 1;
  let y = 1000;
  const ans: number[][] = [];
  while (x <= 1000 && y) {
    const t = customfunction.f(x, y);
    if (t < z) {
      ++x;
    } else if (t > z) {
      --y;
    } else {
      ans.push([x--, y--]);
    }
  }
  return ans;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文