[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 such that a2 + b2 = c.

Example 1:

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

Example 2:

Input: 3
Output: False

Approach #1 Brute Force [Time Limit Exceeded]
bool judgeSquareSum(int c) {
    int i,j;
    for(i=0;i*i<=c;i++)
        for(j=0;j*j<=c;j++)
        {
            if(i*i+j*j==c)
                return true;
        }
    return false;
}

此方法虽然简单,但是给定一个比较大的数时,往往在指定时间内求不出结果。

Approach #2 Better Brute Force [Time Limit Exceeded]

We can improve the last solution, if we make the following observation. For any particular aaa chosen, the value of bbb required to satisfy the equation a2+b2=ca^2 + b^2 = ca2+b2=c will be such that b2=c−a2b^2 = c - a^2b2=ca2. Thus, we need to traverse over the range (0,c)(0, \sqrt{c})(0,c) only for considering the various values of aaa. For every current value of aaa chosen, we can determine the corresponding b2b^2b2 value and check if it is a perfect square or not. If it happens to be a perfect square, ccc is a sum of squares of two integers, otherwise not.

Now, to determine, if the number c−a2c - a^2ca2 is a perfect square or not, we can make use of the following theorem: "The square of nthn^{th}nth positive integer can be represented as a sum of first nnn odd positive integers." Or in mathematical terms:

n2=1+3+5+...+(2∗n−1)=∑1n(2∗i−1)n^2 = 1 + 3 + 5 + ... + (2*n-1) = \sum_{1}^{n} (2*i - 1)n2=1+3+5+...+(2n1)=1n(2i1).

To look at the proof of this statement, look at the L.H.S. of the above statement.

1+3+5+...+(2∗n−1)=1 + 3 + 5 + ... + (2*n-1)=1+3+5+...+(2n1)=

(2∗1−1)+(2∗2−1)+(2∗3−1)+...+(2∗n−1)=(2*1-1) + (2*2-1) + (2*3-1) + ... + (2*n-1)=(211)+(221)+(231)+...+(2n1)=

2∗(1+2+3+....+n)−(1+1+...ntimes)=2*(1+2+3+....+n) - (1+1+...n times)=2(1+2+3+....+n)(1+1+...ntimes)=

2∗n∗(n+1)/2−n=2*n*(n+1)/2 - n=2n(n+1)/2n=

n∗(n+1)−n=n*(n+1) - n=n(n+1)n=

n2+n−n=n2n^2 + n - n = n^2n2+nn=n2

根据以上原理,第一次写出的代码总是运行错误,后来才发现一行代码的位置放错导致逻辑出错。

bool judgeSquareSum(int c) { 
   int i,b;
//    int j=1,sum=0;    该行代码应该放在循环内部,否则对每一个i,j和sum的值将一直增加,
    for(i=0;i*i<=c;i++)
    {
        b=c-i*i;
        int j=1,sum=0;
        while(sum<b)
        {
            sum=sum+j;
            j+=2;
        }
        if(sum==b)
            return true;
    }
    return false;
}

但还是运行时间过长。

Approach #3 Using sqrt function[Time Limit Exceeded]

Algorithm

Instead of finding if c−a2c - a^2ca2 is a perfect square using sum of odd numbers, as done in the last approach, we can make use of the inbuilt sqrtsqrtsqrt function and check if c−a2\sqrt{c - a^2}ca2 turns out to be an integer. If it happens for any value of aaa in the range [0,c][0, \sqrt{c}][0,c], we can return a True value immediately.

bool judgeSquareSum(int c) {
    int i;
    double b;
    for(i=0;i*i<=c;i++)
    {
        b=sqrt(c-i*i);
        if(b==(int)b)
            return true;
    }
    return false;
}

还是时间太长。

最后的代码如下:

bool judgeSquareSum(int c) {
    int left=0,right=(int)sqrt(c);
    while(left<=right)
    {
        int res=left*left+right*right;
        if(res<c)
            left++;
        else if(res>c)
            right--;
        else
            return true;
    }
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值