一、题目

给定一个非负整数 c ,你要判断是否存在两个整数 ab,使得 a + b = c

点击查看原题

二、思路

1)暴力+优化:

解题优先考虑能够做出来,首先想到的就是暴力搜索的方法,由于c已经知道,只需要暴力搜索a和b即可,搜索范围为633. 平方数之和-每日一题 - 图1
对暴力搜索的优化:
很容易想到双重循环找a和b,这样会造成很多的时间浪费,由于633. 平方数之和-每日一题 - 图2,可以只用一次遍历b,不断对a用sqrt函数求解,并判断a是否有小数即可(通过强转类型再判断是否相等即可)

2)双指针

如果我们的双指针begin和end指向区间633. 平方数之和-每日一题 - 图3的头和尾,有三种情况需要考虑:

1)如果633. 平方数之和-每日一题 - 图4,直接返回true 2)如果633. 平方数之和-每日一题 - 图5,则begin = begin + 1 3)如果,则end = end - 1

三、代码

1)暴力优化

  1. class Solution {
  2. public boolean judgeSquareSum(int c) {
  3. int n = (int)Math.sqrt(c);
  4. for (int a = n; a >= 0; a--) {
  5. double b = Math.sqrt(c - a*a);
  6. if (b == (int)b) {
  7. return true;
  8. }
  9. }
  10. return false;
  11. }
  12. }

时间复杂度为633. 平方数之和-每日一题 - 图6,空间复杂度为O(1),但由于sqrt耗费时间较多,表现并不好。

2)双指针

  1. class Solution {
  2. public boolean judgeSquareSum(int c) {
  3. int begin = 0, end = (int)Math.sqrt(c);
  4. while (begin <= end) {
  5. int val = begin * begin + end * end;
  6. if (val == c) {
  7. return true;
  8. }
  9. if (val < c) {
  10. begin++;
  11. } else {
  12. end--;
  13. }
  14. }
  15. return false;
  16. }
  17. }

时间复杂度为633. 平方数之和-每日一题 - 图7,空间复杂度为O(1),每个循环只有两次乘法运算,整体性能较好。