Python世界:力扣题633,平方数之和,中等
- 任务背景
- 思路分析
- 代码实现
- 测试套件
- 本文小结
任务背景
问题来自力扣题目633. Sum of Square Numbers,大意如下:
Given a non-negative integer
c
, decide whether there’re two integersa
andb
such thata^2 + b^2 = c
.
翻译下,需求是:对给定数字c,确定是否有两个整数满足a^2+b^2=c
思路分析
二分法思路
- 默认a,b均为非负,且b不小于a
- 在0-sqrt©之间遍历a,直到a=b相遇或a>b跳出循环
- cs = sqrt©
- 此移动方式不通
- 若b=sqrt(c-a^2) 圆整后,重加回满足目标,且b不小于a中断
- 若b<a,a收缩为下界
- 若b>a,a收缩为上界
- 换为low/high双指针左右移动
- 将0-cs之间的数平方和组合罗列为一种有序组合
- 初始位:t = low2+high2,是在有序组合的中间
- 若t > c,则缩小high
- 若t < c,则增大low
- 与纯二分区别在于,不仅单一mid在移动
代码实现
import math
class Solution(object):
def judgeSquareSum(self, c):
"""
:type c: int
:rtype: bool
"""
res = False
cs = int(math.sqrt(c)) + 1
low = 0
high = cs
while (low <= high): # two pointer
t = low**2 + high**2
if (t < c):
low += 1
elif (t > c):
high -= 1
else:
return True
return res
测试套件
单例测试demo:
# one case test
c = 5 # 1+4
c = 4 # 0+4
c = 3 # false
c = 13 # 4+9
c = 12 # false
c = 169 # 12^2+5^2
sol = Solution()
res = sol.judgeSquareSum(c)
print(res)
测试套demo:
# 导入单元测试
import unittest
def test_base(self, c, ret):
sol = Solution()
res = sol.judgeSquareSum(c)
self.assertEqual(res, ret)
# 编写测试套
class TestSol(unittest.TestCase):
# 不在
def test_special1(self):
c = 3
ret = False
test_base(self, c, ret)
# 下边界
def test_special2(self):
c = 0
ret = True
test_base(self, c, ret)
# 上边界
def test_special3(self):
c = 2**31 - 1
ret = False
test_base(self, c, ret)
def test_common1(self):
c = 5
ret = True
test_base(self, c, ret)
def test_common2(self):
c = 13
ret = True
test_base(self, c, ret)
def test_common3(self):
c = 169
ret = True
test_base(self, c, ret)
# 含测试套版本主调
if __name__ == '__main__':
print('start!')
unittest.main() # 启动单元测试
print('done!')
本文小结
本题思路很简单,只为重温下二分写法,发现值大的下移上界,发现值小的上移下界,直到上下界重合。要特别注意的是无target时,mid的偏移问题。