Problem Description#
Check out the problem on Leetcode
Given a non-negative integer \(c\), decide whether there exists two integers \(a\) and \(b\) such that \(a^2+b^2=c\)
Solution#
Try different combinations of \((a,b)\), adjusting the guess each time based on whether their sum is too large or too small. I define \(a\) as the smaller value and \(b\) as the larger value.
Initial values#
- \(a=0\)
 - \(b^2>=c\)
 - \(\text{sum}=b^2\)
 
Finding the solution#
If the sum is too big, then make \(b\) smaller. If it is too large, make \(a\) larger. Stop when \(a>b\).
Optimising sum calculation#
\((a+1)^2 = a^2+2a+1\)
\((b-1)^2 = b^2-2b+1\)
We can use this to update sum:
\((a+1)^2+b^2 = a^2+2a+1+b^2\)
\( \quad \quad \quad \quad \quad \ \ \ = \text{sum} + 2a + 1\)
Therefore, instead of recalculating the sum each time using a*a+b*b, we can instead use these formulae. For example, if increasing a, sum += 2a+1.
Complexity#
Time complexity: O(\(\sqrt{n}\) )
Space complexity: O(1)
Code#
bool judgeSquareSum(const int& c) {
    // let a<=b
    unsigned int a = 0;
    unsigned int b = ceil(sqrt(c));
    unsigned int sum = b*b;
    while(a<=b){
        if(sum==c){
            return true;
        }
        else if(sum<c){
            // increase a
            // (a+1)^2 = a^2 +2a+1
            sum += 2*a+1;
            a++;
        }
        else{
            // decrease b
            // (b-1)^2 = b^2-2b+1
            sum += 1-2*b;
            b--;
        }
    }
    return false;
}

