[路飞]_每天刷leetcode_01(平方数之和)

424 阅读1分钟

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

算法训练之 平方数之和

今天我们一起来学习一道关于数字计算的算法题,是 leetcode 上的 633题。小伙伴们可以先自己做一遍。

平方数之和 leetcode传送门

题目

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

Given a non-negative integer c, decide whether there're two integers a and b such that a2 + b2 = c.

Ecample:

Input: c = 5
Output: true
Explanation: 1 * 1 + 2 * 2 = 5

Input: c = 4
Output: true
Explanation: 0 * 0 + 2 * 2 = 4

解题

  1. 枚举法 我们可以枚举 a ( 0<= a <= Math.sqrt(c)). 然后检查是否存在整数 b使得等式成立。

    /**
     * @param {number} c
     * @return {boolean}
     */
    var judgeSquareSum = function(c) {
        for(let i = 0; i <= Math.floor(Math.sqrt(c)); i ++) {
            const   b = Math.sqrt(c - i * i);
            if(b === parseInt(b)) return true;
        }
        return false;
    };
    
  2. 双指针法 a和 b的范围一定是在 [0, Math.sqrt(c)]之间。我们也可以使用双指针 在a、b值的范围内进行缩小范围,直到找到真正的结果则返回 true; 或者找到 较小值不大于较大值仍没找到结果,返回 false.

    /**
     * @param {number} c
     * @return {boolean}
     */
    var judgeSquareSum = function(c) {
        let a = 0; b  = Math.floor(Math.sqrt(c));
        while(a <= b) {
            if(a **2 + b **2 === c) return true;
            if(a **2 + b **2 < c) a++;
            if(a **2 + b **2 > c) b--;
        }
        return false;
    };
    
    1. 费马平方和

    费马平方和定理: 一个非负整数 c 如果能够表示为两个整数的平方和,当且仅当 c 的所有形如 4k+3 的质因子的幂均为偶数时成立。 根据此定理可以获得解法

    /**
     * @param {number} c
     * @return {boolean}
     */
    var judgeSquareSum = function(c) {
        for(let i = 2; i <= Math.floor(Math.sqrt(c)); i ++) {
            if(c % i !== 0) {
                continue; // 不是因子,下一个
            }
    
            let exp = 0;
            while(c % i ===0) { // 计算 i的幂
                c/= i;
                exp ++;
            }
            if(i % 4 ===3 && exp %2 !==0) { //根据平方和定理验证
                return false;
            }
            
        }
        return c % 4 !==3;
    };
    

    好了,这就是今天刷题的全部内容,小伙伴们学会了吗?