Given a non-negative integer c, your task is to decide whether there're two integers a and b such that a2 + b2 = c.

Example 1:

Input: 5
Output: True
Explanation: 1 * 1 + 2 * 2 = 5

Example 2:

Input: 3
Output: False

这道题让我们求一个数是否能由平方数之和组成,刚开始博主没仔细看题,没有看到必须要是两个平方数之和,博主以为任意一个就可以。所以写了个带优化的递归解法,博主已经不是上来就无脑暴力破解的辣个青葱骚年了,直接带优化。可是居然对 14 返回 false,难道 14 不等于 1+4+9 吗,结果仔细一看,必须要两个平方数之和。好吧,那么递归都省了,直接判断两次就行了。我们可以从c的平方根,注意即使c不是平方数,也会返回一个整型数。然后我们判断如果 i*i 等于c,说明c就是个平方数,只要再凑个0,就是两个平方数之和,返回 true;如果不等于的话,那么算出差值 c - i*i,如果这个差值也是平方数的话,返回 true。遍历结束后返回 false,参见代码如下:

解法一:

class Solution {
public:
bool judgeSquareSum(int c) {
for (int i = sqrt(c); i >= ; --i) {
if (i * i == c) return true;
int d = c - i * i, t = sqrt(d);
if (t * t == d) return true;
}
return false;
}
};

下面这种方法用到了 HashSet,从0遍历到c的平方根,对于每个i*i,都加入 HashSet 中,然后计算 c - i*i,如果这个差值也在 HashSet 中,返回 true,遍历结束返回 false,参见代码如下:

解法二:

class Solution {
public:
bool judgeSquareSum(int c) {
unordered_set<int> s;
for (int i = ; i <= sqrt(c); ++i) {
s.insert(i * i);
if (s.count(c - i * i)) return true;
}
return false;
}
};

上面两种方法都不是很高效,来看下面这种高效的解法。论坛上有人称之为二分解法,但是博主怎么觉得不是呢,虽然样子很像,但是并没有折半的操作啊。这里用a和b代表了左右两个范围,分别为0和c的平方根,然后 while 循环遍历,如果 a*a + b*b 刚好等于c,那么返回 true;如果小于c,则a增大1;反之如果大于c,则b自减1,参见代码如下:

解法三:

class Solution {
public:
bool judgeSquareSum(int c) {
long a = , b = sqrt(c);
while (a <= b) {
if (a * a + b * b == c) return true;
else if (a * a + b * b < c) ++a;
else --b;
}
return false;
}
};

下面这种解法基于费马平方和定理 Fermat's theorem on sums of two squares 的一般推广形式:当某个数字的 4k+3 型的质数因子的个数均为偶数时,其可以拆分为两个平方数之和(each prime that is congruent to 3 mod 4 appears with an even exponent in the prime factorization of the number)。那么我们只要统计其质数因子的个数,并且判读,若其为 4k+3 型且出现次数为奇数的话直接返回 false。这里,我们从2开始遍历,若能整除2,则计数器加1,并且c也要除以2。这样我们找到都会是质数因子,因为非质数因子中的因子已经在之前被除掉了,这也是个 trick,需要自己好好想一下。最终在循环退出后,我们还要再判断一下,若剩余的质数因子还是个 4k+3 型,那么返回 false,否则返回 true,参见代码如下:

解法四:

class Solution {
public:
bool judgeSquareSum(int c) {
for (int i = ; i * i <= c; ++i) {
if (c % i != ) continue;
int cnt = ;
while (c % i == ) {
++cnt;
c /= i;
}
if (i % == && cnt % != ) return false;
}
return c % != ;
}
};

类似题目:

Valid Perfect Square

参考资料:

https://leetcode.com/problems/sum-of-square-numbers/

https://leetcode.com/problems/sum-of-square-numbers/discuss/104938/simple-c-solution

https://leetcode.com/problems/sum-of-square-numbers/discuss/104930/java-two-pointers-solution

https://leetcode.com/problems/sum-of-square-numbers/discuss/104932/hashset-java-quick-solution-one-for-loop

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Sum of Square Numbers 平方数之和的更多相关文章

  1. [LeetCode] 633. Sum of Square Numbers 平方数之和

    Given a non-negative integer c, your task is to decide whether there're two integers a and b such th ...

  2. LeetCode 633. Sum of Square Numbers平方数之和 (C++)

    题目: Given a non-negative integer c, your task is to decide whether there're two integers a and b suc ...

  3. Leetcode633.Sum of Square Numbers平方数之和

    给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c. 示例1: 输入: 5 输出: True 解释: 1 * 1 + 2 * 2 = 5 示例2: 输入: 3 ...

  4. [LeetCode] Sum of Two Integers 两数之和

    Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Exam ...

  5. LeetCode Sum of Square Numbers

    原题链接在这里:https://leetcode.com/problems/sum-of-square-numbers/description/ 题目: Given a non-negative in ...

  6. C#版 - Leetcode 633. 平方数之和 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  7. C#刷遍Leetcode面试题系列连载(4) No.633 - 平方数之和

    上篇文章中一道数学问题 - 自除数,今天我们接着分析 LeetCode 中的另一道数学题吧~ 今天要给大家分析的面试题是 LeetCode 上第 633 号问题, Leetcode 633 - 平方数 ...

  8. Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted)

    Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted) 给定一个已按照升序排列 的有序数组,找到两个数使得它们 ...

  9. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

随机推荐

  1. MSIL实用指南-装箱拆箱

    本篇讲述怎样装箱拆箱.装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大. 装箱装箱指令是Box.使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型& ...

  2. PHP 相对完整的分页

    效果链接http://love.bjxxw.com/oejiaoyou/pubu/zhaopian.php php 分页 <?php /* * * * 说明 吉海波 2015/9/17 * $p ...

  3. [日常] NOIP 2017滚粗记

    突然挑了这么个滑稽的时间补了游记... (成绩日常延时再加上人太菜估计基本上就是颓废记录) 然而文化课太废可能会被强制退役QAQ所以先补了再说吧 day0 一大早被老姚交代了个开十一机房门的任务... ...

  4. JavaWeb学习笔记八 监听器

    监听器Listener jservlet规范包括三个技术点:servlet :listener :filter:监听器就是监听某个对象的的状态变化的组件.监听器的相关概念事件源: 被监听的对象(三个域 ...

  5. C语言程序设计(基础)- 第2周作业

    1.阅读提问的智慧,要求仔细阅读链接内容,用自己的话描述你的收获,并举例子说明应该如何提问. 2.所有同学请在自己电脑上配置git.编译器(win10 系统的话就Dev-C++).翻译软件,十一回校后 ...

  6. 听翁恺老师mooc笔记(7)--字符串1

    C语言中字符串的定义 如果定义一个字符数组word,并使用大括号对其初始化,如下图所示: 但是这个不是C语言的字符串,只是字符数组,不是字符串,因为不能使用字符串的方式进行计算.那么C语言的字符串长什 ...

  7. 学号:201621123032 《Java程序设计》第12周学习总结

    1:本周学习总结 1.1:以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2:面向系统综合设计-图书馆管理系统或购物车 2.1: 简述如何使用流与文件改造你的系统.文件中数据的格式如何? ...

  8. 201621123031 《Java程序设计》第5周学习总结

    作业05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键字:接口.继承.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需 ...

  9. R语言基础2

    ----------------------------------R语言学习与科研应用,科研作图,数据统计挖掘分析,群:719954246-------------------------- 通常, ...

  10. linux的脚本应用for循环答应变量

    #!/bin/bash for var in A B C ; do echo "var is $var" done