题目重点:包含a0和a=b,严格s<n,不把第三种表示误当两种。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 非负整数a/b,(a,b)与(b,a)同一表示,允许a=b与0;返回全部s<n恰两种表示。
- 原值域n可近2³¹,枚举代码是正确基线但不是对最大范围的可承诺性能方案,需讨论预算/分段或数论优化。
解题路线
- a到isqrt(n−1),b从a到isqrt(n−1−a²)。这刚好枚举每个无序合法pair一次。累加counts[s],超过2后饱和为3保留“至少3”状态。
- 最后选择count==2并排序。不能提前在第二次命中时输出,因为以后可能第三次出现;也不能饱和在2。
- 枚举区域是半个四分之一圆,pair数量Θ(n),不是只有外层√n就O(√n)。最大输入可能需数亿pair及巨大map,面试应明确此规模风险和优化目标。
手动走一遍
50=1²+7²=5²+5²,两种,输出50;25=0²+5²=3²+4²也两种。0仅(0,0)一种,不输出。末值n本身不包含,n50时50不输出。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from math import isqrt
def exactly_two(n):
if type(n) is not int or n<1:raise ValueError("positive integer bound required")
counts={}
for a in range(isqrt(n-1)+1):
for b in range(a,isqrt(n-1-a*a)+1):
value=a*a+b*b;counts[value]=min(3,counts.get(value,0)+1)
return sorted(value for value,count in counts.items() if count==2)
复杂度
枚举Θ(n)整数操作、map最坏O(n)条;排序O(AlogA),A输出数。大整数isqrt/乘法位成本另计。
易错点与追问
容易失分的边界
- 漏a=0会漏平方数轴表示。
- 用floor(sqrt(float))可能边界舍入,整数isqrt更稳。
继续深挖
- 只查询单个s是否恰两种时怎样少枚举一个维度?
- n很大而内存有限,如何分段累计并明确重复扫描成本?
