leetcode——633.平方数之和

经过40多分钟才写出来,应该还是思路的问题。

但是通过了我就很开心

 1 class Solution:
 2     def judgeSquareSum(self, c: int) -> bool:
 3         if c==0:
 4             return True
 5         
 6         i=int((c//2)**0.5)
 7         j=int((c//2)**0.5)+1
 8         while i<int(c**0.5)+1 and j>=0:
 9             if i**2+j**2==c:
10                 return True
11             elif i**2+j**2>c:
12                 j=j-1
13             elif i**2+j**2<c:
14                 i=i+1
15         else:
16             return False
执行用时 :940 ms, 在所有 Python3 提交中击败了5.23%的用户
内存消耗 :13.8 MB, 在所有 Python3 提交中击败了8.44%的用户
 
举个例子:
假如c=78
因为c大于8**2,小于9**2,
所以遍历的时候 i 的大小最大也就是8。因为是两个数的平方和,所以最公平的就是i**2和j**2各占c/2。
所以i的起始值就是从根号c/2开始,到根号c结束;
j从根号2/c+1开始,依次减小,到0结束。
遍历过程以及判断条件如程序中所示
 
这个我竟然看不懂。。。。。。
然后发现,看不懂是因为我不知道这个定理:
''' 定理:某个正整数是两平方数之和,当且仅当该正整数的所有 4k+3 型素因数的幂次均为偶数。 任何一个正整数都可以因数分解为 c = (2^r)*(p1^n1)*(p2^n2)*...*(pk^nk),其中p1...pk为素因数,n1...nk为因数的幂次。 也就是说有一个形如4k+3的素因数pi,如果ni为奇数,那它就不可能被写为两个整数的平方数之和了。 '''
 
 
代码第一步是将2全部去掉,做素因数分解
if c <= 2:
            return True
        while c % 2 == 0:
            c = c // 2

做因数分解的同时,判断素因数的类型和幂次

p = 3
        while p * p <= c:
            index = 0
            while c % p == 0:
                index += 1
                c = c // p
            if (p % 4 == 3) and (index % 2 == 1):
                return False
            p += 2

#分解到最后的c实际上是一个素数,这时候如果判断c是形如4k+1的素数,那肯定可以写为两整数平方和(也可以判断不是形如4k+3的素数也行)  这个不太看得透。。。

return c % 4 == 1

这个跟我的思路一样,但是比我写的简洁清爽。

while i <= j:
            total = i * i + j * j

这一句用得很棒。

这就是区别啊,明明也想到了,但是就差一个火候

                                                                                     ——2019.9.25
 

 

posted @ 2019-09-25 13:46  欣姐姐  阅读(302)  评论(0编辑  收藏  举报