• [CodeWars][JS]如何判断给定的数字是否整数


    问题描述:

    We are asking for a function to take a positive integer value, and return a list of all positive integer pairs whose values - when squared- sum to the given integer.

    For example, given the parameter 25, the function could return two pairs of 5,0 and 3,4 because 5^2 + 0^2 = 25 and 3^2 + 4^2 = 25.

    We might express that in pseudo-code like this:

    allSquaredPairs(25) == [[5,0],[3,4]];
    

     题目本身比较简单,就是给定一个整数,求出平方和等于该整数的两个数的序列。

    解法

    方法1:遍历所有数字以得到结果

    function allSquarePairs(num){
        var temp = Math.sqrt(num);
        var result = [];
        for(var i=0; i<=temp; i++){
            for(var j=i; j<=temp; j++)
                if(i*i+j*j==num)
                  result.push([i,j]);
        }
        return result;
    }
    

     然而虽然这个方法是正确的,却无法通过测试。因为这个算法的复杂度还是蛮大的,遇到很大的num就得花比较久的时间才能得出结果了。

    那么怎么降低复杂度呢?我觉得问题主要出在j的遍历上。对于每个i,j都得从头遍历一次,这显然贡献了不少的计算量。

    我想了想,或许可以用二分查找,每给定一个i,就在i与temp之间取中值,若j太大,则在前一个区间继续遍历;太小,则换成下一个区间。

    正当我绞尽脑汁地想怎么完美地植入二分法的时候,忽然灵光一闪,其实根本没有必要这么复杂的:给定了一个i之后,其实我们可以通过计算直接得出j的值,完全没有必要遍历的……

    方法2: 直接计算j的值

    function allSquaredPairs(num) {
      var temp = Math.sqrt(num);
      var result = [];
      var j=0;
      for(var i=0; i<=temp; i++){
        j=Math.sqrt(num-i*i);
        if(isInt(j) && j>=i)
          result.push([i,j]);
      }
      return result;
    }
    

     以上,遍历i的时候,通过计算(num-i^2)的平方根,判断是否为整数,如果是,则得到了一组值,否则继续检索。如此一来少了一个循环计算量就大大减少了,顺理成章地通过了测试。

    改进

    1> isInt()的实现

    上面的代码中isInt()表示判断一个数字是否为整数,是则返回true,否则为false。

    当然这里没必要使用过函数,用简单的表达式会更方便一些,这里只是为了占个位。

    那么问题来了,怎样判断一个数字是否为整数呢?

    在玩这道题之前,我知道有这些方法:

    a>Math.floor(num) == num

    对给定的数字取整,如果与原来的数字相等,则为整数。

    b>parseInt(num) == num

    和上面一样的,只不过使用不同的方法

    c>"^-?//d+$"

    当然还可以使用强大的正则表达式。

    做完这道题之后我才意识到还有更简洁的形式:

    d>num == num | 0

    num | 0 舍弃了小数部分,和Math.floor()有些相似。不过还是不一样的,如果num是负数的时候区别就出来了。

    f>num == ~~num

    和上面一样的~

    g>num == num>>0

    同上~

    g>num%1 == 0

    与上面的几个方法相反,这里检测的是小数部分。

    2> 冗余的判断条件

    在isInt()的旁边我们还做了一个j>i的条件,以此避免出现重复序列,比如[0,5]和[5,0]。

    实际上这点完全可以在设置temp的值时就过滤掉。只要让temp=Math.sqrt(num/2)而不是temp=Math.sqrt(num),就可以去掉后面这个j>i的条件了。

  • 相关阅读:
    consumer详解
    消费幂等
    死信队列
    消息重试
    负载均衡
    存储层
    producer消息
    消息发送与接收
    TCC
    form表单提交前进行加密
  • 原文地址:https://www.cnblogs.com/kindofblue/p/4654126.html
Copyright © 2020-2023  润新知