1237. 找出给定方程的正整数解
大约 3 分钟
---
1237. 找出给定方程的正整数解
- 标签:数学、双指针、二分查找、交互
- 难度:中等
题目链接
题目大意
描述:给你一个函数 和一个目标结果 ,函数公式未知。已知函数是单调递增的: 且 。 和 都是正整数( 到 )。
要求:计算方程 所有可能的正整数数对,并按任意顺序返回。
说明:
- 。
- 。
示例:
- 示例 1:
输入:function_id = 1, z = 5
输出:[[1,4],[2,3],[3,2],[4,1]]
解释:function_id = 1 暗含的函数式子为 f(x, y) = x + y- 示例 2:
输入:function_id = 2, z = 5
输出:[[1,5],[5,1]]
解释:function_id = 2 暗含的函数式子为 f(x, y) = x * y解题思路
思路 1:双指针
1. 核心思想
因为 关于 和 都是单调递增的,我们可以利用这个性质,用双指针法从两个方向逼近目标值。
具体做法是:固定 从最小的 开始, 从最大的 开始。这样在搜索过程中:
- 如果 ,说明值太小了。由于 已经不能再增大(它从最大值开始),需要增大 来让值变大。
- 如果 ,说明值太大了。由于 已经不能再减小(它从最小值开始),需要减小 来让值变小。
- 如果相等,记录结果,然后同时移动两个指针( 增大, 减小)继续搜索。
这个过程就像在一个二维单调矩阵中搜索目标值, 和 分别沿着一个方向走,不会走回头路,所以 和 最多各移动 步。
2. 具体步骤
第 1 步:初始化 ,,结果列表 。
第 2 步:当 且 时循环:
- 调用 获取当前值 。
- 如果 :(值偏小,增大 )。
- 如果 :(值偏大,减小 )。
- 如果 :将 加入 ,然后 ,(继续搜索其他解)。
第 3 步:返回 。
结合示例 1 走一遍:
双指针搜索过程:
- : →
- ...不断减小 直到...
- : → 记录 ,
- : → 记录 ,
- : → 记录 ,
- : → 记录 ,
,结束。结果:。
思路 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 >= 1:
val = customfunction.f(x, y)
if val < z:
x += 1 # 值偏小,增大 x
elif val > z:
y -= 1 # 值偏大,减小 y
else:
ans.append([x, y])
x += 1
y -= 1 # 找到一个解后继续搜索
return ans思路 1:复杂度分析
- 时间复杂度:。 最多从 增加到 , 最多从 减小到 ,总共移动步数不超过 ,是常数时间。
- 空间复杂度:,不考虑存储答案所需的空间。