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. mysql增加索引、删除索引、查看索引

    添加索引 有四种方式来添加数据表的索引: 1.添加一个主键,这意味着索引值必须是唯一的,且不能为NULL ALTER TABLE tbl_name ADD PRIMARY KEY (column_li ...

  2. Asp.Net后台弹出确认提示窗Confirm

    前端js代码: function MyConfirm(message, guid) { if (confirm(message) == true) { document.getElementById( ...

  3. 安装Yapi时,出现json-schema-faker模块找不到问题

    今天换了一台机器按以前的方式安装Yapi工具时,竟然出现了错误. 一 安装yapi时,出现了下面的报错,一开始以为没安装json-schema-faker模块.后面通过找资料,发现是权限问题, 使用c ...

  4. centos7安装jdk1.7(rpm版)

    一.环境 centos7 jdk-7u80-linux-x64.rpm下载:链接:https://pan.baidu.com/s/10UMrxNE1d2ZbDt7kvBM1yQ   提取码:pmov  ...

  5. DevExpress的TreeList怎样设置数据源使其显示成单列树形结构

    场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...

  6. mssql SQL Server 2008 阻止保存要求重新创建表的更改问题的设置方法

    解决方法: 工具-〉选项-〉左侧有个 设计器-〉表设计器和数据库设计器 -> 阻止保存要求重新创建表的更改(右侧) 把钩去掉即可.

  7. 英文DIAMAUND钻石DIAMAUND词汇

    首先谈谈钻石和金刚石的名称.金刚石是一种天然矿物,是钻石的原石.习惯上人们常将加工过的金刚石称为钻石,而未加工过的称为金刚石(当然,有的金刚石不用加工便可应用).钻石是那些达到宝石级别的金刚石晶体切磨 ...

  8. 9.InfluxDB-InfluxQL基础语法教程--LIMIT and SLIMIT 子句

    本文翻译自官网,官网地址:(https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/) LIMIT和SLIM ...

  9. Python从零开始——集合Set

    一:Python集合知识概览 二:Python的特性.格式.以及各序列结构对比 三:Python集合set的创建 四:集合常用操作之——添加元素 五:集合常见操作之——删除元素 六:集合常见操作之—— ...

  10. xshell 远程登陆CentOS7 免密登陆

    首先说一下大体的思路: 1. 以密码登陆CentOS系统 2. 配置ssh 3. xshell 生成秘钥 4. 进行免密登陆 软件.设备: xshell(下载地址(免费版),也可以自行百度下载) Ce ...