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] 633. Sum of Square Numbers 平方数之和的更多相关文章

  1. 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 ...

  2. [LeetCode] 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 ...

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

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

  4. #Leetcode# 633. Sum of Square Numbers

    https://leetcode.com/problems/sum-of-square-numbers/ Given a non-negative integer c, your task is to ...

  5. 【Leetcode_easy】633. Sum of Square Numbers

    problem 633. Sum of Square Numbers 题意: solution1: 可以从c的平方根,注意即使c不是平方数,也会返回一个整型数.然后我们判断如果 i*i 等于c,说明c ...

  6. 【LeetCode】633. Sum of Square Numbers 解题报告(python & Java & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 列表生成式 循环 日期 题目地址:https ...

  7. 【leetcode】633. Sum of Square Numbers(two-sum 变形)

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

  8. 【LeetCode】633. Sum of Square Numbers

    Difficulty: Easy  More:[目录]LeetCode Java实现 Description https://leetcode.com/problems/sum-of-square-n ...

  9. 633. Sum of Square Numbers【Easy】【双指针-是否存在两个数的平方和等于给定目标值】

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

随机推荐

  1. SAP PI开发手册-ERP发布服务供外围系统调用(RFC类型)

    1转自:https://www.cnblogs.com/fanjb/p/10677018.html 8年进入国网项目后陆陆续续做了一些接口,按实现方法去分有RFC和代理类sproxy类型,按服务提供方 ...

  2. convert datatable to List<T>

    public class DataConvert { public static List<T> ConvertDataTable<T>(DataTable dt) { Lis ...

  3. .net webapi跨域问题

    2019年11月8日,近期做项目开始实行前后端分离的方式开发,前端使用vue的框架,打包发布后,调用后端接口出现跨域的问题,网上搜索出来的都是以下的配置方式: 但是,在我的项目中,按这种方式配置没有效 ...

  4. Vue监控器watch的全面解析

    前言 前面讲到了计算属性computed,这次讲的是监控器watch,主要任务就是监控变量的变化 正文 watch是一个对象,键是需要观察的表达式,值是对应回调函数.值也可以是方法名,或者包含选项的对 ...

  5. QTableWidget获取选中行内容

    QList<QTableWidgetItem*> items = ui->tableWidget->selectedItems(); int count = items.cou ...

  6. Oracle 11G空表无法导出处理

    通过exp进行数据导出的时候,如果表的数据为空,则会出现警告,并且表也不会导出,不利于数据恢复. 可以通过以下方法进行解决: 一.使用ALLOCATE EXTENT,可以导出之前已经存在的空表 --查 ...

  7. 如何fork自己的github库?

    Github上我们经常fork其他人的代码,然后经过一通魔改后弄出"自己"的东西.但是现在我遇到了这么一个需求,就是我已经公开了一个自己的库(暂且叫parent),然后我想基于自己 ...

  8. echarts-带面积的折线图

    测试地址 https://gallery.echartsjs.com/editor.html?c=x6p5SsIEzt var listN = '高温'; var unit = '°C'; //单位 ...

  9. Spring(002)-创建rest服务

    1.创建基于get参数的rest服务 @RestController @RequestMapping("/action") public class GetController { ...

  10. 201871010109-胡欢欢《面向对象程序设计(java)》第6-7周学习总结

    实验六 继承定义与使用 实验时间 2019-9-29 第一部分:理论部分. 1.继承:已有类来构建新类的一种机制.档定义了一个新类继承另一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的 ...