How to Determine Sum of Two Square Numbers?

  • 时间:2020-10-05 13:15:44
  • 分类:网络文摘
  • 阅读:161 次

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

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

Example 2:
Input: 3
Output: False

This is a typical/classic math problem, and the computer is very good at solving it by bruteforce algorithms.

Bruteforce Algorithm to Check Sum of Two Square Numbers

The following C++ implements the bruteforce with no optimisation, which runs at O(C) complexity.

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a <= c; ++ a) {
            for (unsigned int b = 0; b * b <= c; ++ b) {
                if (a * a + b * b == c)
                    return true;
            }
        }
        return false;
    }    
};
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a <= c; ++ a) {
            for (unsigned int b = 0; b * b <= c; ++ b) {
                if (a * a + b * b == c)
                    return true;
            }
        }
        return false;
    }    
};

Optimised Bruteforce Algorithm

We know that n-th square number is the sum of the n-th odd number. For example, 9 = 1 + 3 + 5, and 16 = 1 + 3 + 5 + 7 … Therefore, we can reduce the runtime for the inner loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a <= c; ++ a) {
            int b =  c - a * a;
            if (isSquare(b)) {
                return true;
            }
        }
        return false;
    }    
 
private:
    inline bool isSquare(unsigned int b) {
        unsigned int i = 1, sum = 0;
        while (sum < b) {
            sum += i;
            i += 2;
        }
        return sum == b;
    }
};
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a <= c; ++ a) {
            int b =  c - a * a;
            if (isSquare(b)) {
                return true;
            }
        }
        return false;
    }    

private:
    inline bool isSquare(unsigned int b) {
        unsigned int i = 1, sum = 0;
        while (sum < b) {
            sum += i;
            i += 2;
        }
        return sum == b;
    }
};

This optimisation is great, however, the approach still runs at O(C) complexity.

Using SQRT

In fact, we can compute the b value once a is determined, we just need to check if b is an integer, which can be done using the sqrt function, that runs at O(logC).

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a <= c; ++ a) {
            int b = (int)sqrt(c - a * a);
            if ((unsigned long)b * b + (unsigned long)a * a == c) {
                return true;
            }
        }
        return false;
    }    
};
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a <= c; ++ a) {
            int b = (int)sqrt(c - a * a);
            if ((unsigned long)b * b + (unsigned long)a * a == c) {
                return true;
            }
        }
        return false;
    }    
};

The overall complexity is O(sqrt(c)log(c)).

Using Binary Search to Determine if An integer is sum of two square integers

Last but not least, we can use the binary search to determine if an integer is a square – that runs at O(logN) complexity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a < = c; ++ a) {
            unsigned int b = c - a * a;
            if (binarySearch(0, b, b)) {
                return true;
            }
        }
        return false;
    }    
    
    bool binarySearch(unsigned int left, unsigned int right, unsigned int n) {
        if (left > right) return false;
        int64_t mid = left + (right - left) / 2;
        if (mid * mid == n) return true;
        if (mid * mid > n) {
            return binarySearch(left, mid - 1, n);
        }
        return binarySearch(mid + 1, right, n);
    }
};
class Solution {
public:
    bool judgeSquareSum(int c) {
        for (unsigned int a = 0; a * a < = c; ++ a) {
            unsigned int b = c - a * a;
            if (binarySearch(0, b, b)) {
                return true;
            }
        }
        return false;
    }    
    
    bool binarySearch(unsigned int left, unsigned int right, unsigned int n) {
        if (left > right) return false;
        int64_t mid = left + (right - left) / 2;
        if (mid * mid == n) return true;
        if (mid * mid > n) {
            return binarySearch(left, mid - 1, n);
        }
        return binarySearch(mid + 1, right, n);
    }
};

This approach also runs at O(log(C)sqrt(C)) complexity.

--EOF (The Ultimate Computing & Technology Blog) --

推荐阅读:
卫生部颁布:预包装食品营养标签通则  申请百度联盟,几次三番都不成功啊!  新浪sae不支持写操作,需要移植代码!  维生素B2(核黄素)的食物来源  维生素B1(硫胺素)的食物来源  公众最担心食品添加有毒有害物质  食品安全蓝皮书发布 解读2012食品问题  购买保健食品要认准“蓝帽子”标志  食品安全问题公众和媒体也有话语权  初春食补:胡椒根对症食疗祛除寒湿 
评论列表
添加评论