LeetCode-Python-633. 平方数之和
给定一个非负整数 c
,你要判断是否存在两个整数 a
和 b
,使得 a2 + b2 = c。
示例1:
输入: 5 输出: True 解释: 1 * 1 + 2 * 2 = 5
示例2:
输入: 3 输出: False
第一种思路:
设k = int(sqrt(c)), 如果c自身就是一个完全平方数,即k * k = c,则 c 可以和 0 组,所以返回True。
如果c不是一个完全平方数,
那么可以把1 ~ k的平方记录在一个数组record里,record = [1, 4, 9, ......., k * k]
然后线性扫描record, 对record里的每一个元素x,判断一下 c - x 在不在record里,如果在,就返回True。
如果找不到就返回False。
时空复杂度分析:
record数组长度为K = sqrt(N),每个元素都要扫到;判断补集在不在用二分查找 logK;
所以时间复杂度一共是O(KlogK), K = sqrt(N)
空间复杂度 O(K)
class Solution(object):
def judgeSquareSum(self, c):
"""
:type c: int
:rtype: bool
"""
if c == (int(c ** 0.5) ** 2):
return True
record = list()
for i in range(1, int(c ** 0.5) + 1):
record.append(i **2)
def find(n):
lo, hi = 0, len(record) - 1
while(lo <= hi):
mid = (lo + hi) // 2
if record[mid] == n:
return True
elif record[mid] > n:
hi = mid - 1
else:
lo = mid + 1
return False
for i, x in enumerate(record):
if find(c - x):
return True
return False
第二种思路:
其实这道题就是Two Sum……
所以用hashmap的方法可以提高查找的速度。
时间复杂度O(K)。
class Solution(object):
def judgeSquareSum(self, c):
"""
:type c: int
:rtype: bool
"""
if c == (int(c ** 0.5) ** 2):
return True
record = list()
for i in range(1, int(c ** 0.5) + 1):
record.append(i **2)
hashmap = dict()
for i, x in enumerate(record):
if x + x == c:
return True
if hashmap.get(c - x, 0):
return True
hashmap[x] = x
return False
第三种思路:
既然record数组有序,所以还可以用双指针的方法来做two sum。
时间复杂度O(K)。
class Solution(object):
def judgeSquareSum(self, c):
"""
:type c: int
:rtype: bool
"""
if c == (int(c ** 0.5) ** 2):
return True
record = list()
for i in range(1, int(c ** 0.5) + 1):
record.append(i **2)
lo, hi = 0, len(record) - 1
while(lo <= hi):
s = record[lo] + record[hi]
if s == c:
return True
elif s > c:
hi -= 1
else:
lo += 1
return False
第四种思路:
观察了一下,record其实可以不用生成……
直接用每个数的平方算就可以了……
时间复杂度O(K)
空间复杂度O(1)
class Solution(object):
def judgeSquareSum(self, c):
"""
:type c: int
:rtype: bool
"""
if c == (int(c ** 0.5) ** 2):
return True
lo, hi = 0, int(c ** 0.5)
while(lo <= hi):
s = lo ** 2 + hi ** 2
if s == c:
return True
elif s > c:
hi -= 1
else:
lo += 1
return False
可以看到 加速效果还是很明显的