Codewars刷题思路和心得分享(JS) -----1~5

282 阅读5分钟

梦开始的地方

PS

  刚开始刷题,题目可能比较简单,解题代码可能比较繁琐,大家见谅。

1. 毕达哥拉斯三元组(Pythagorean Triple)

描述

给定一个包含 3 个正整数的**未排序**数组,确定是否可以使用这 3 个整数形成[毕达哥拉斯三元组]。
 即[ n1, n2, n3 ]。毕达哥拉斯三元组由排列 3 个整数组成,使得:一个 a**2 + b**2 = c**2
 若是,则返回 ture, 否则返回 false
 

思路

先找到数组中最大的那个数,把它存到声明的变量 x 中,再令它的值为0, 再遍历这个数组,
把数组的每个元素的平方相加得到sum,比较 sum 和 x 的平方, 判断两个数是否相等。

代码

function isPythagoreanTriple(integers) {
    var x = Math.max(...integers);
    var sum = 0;
    for(let i = 0; i < 3; i ++) {
        if(integers[i] == x) {
            integers[i] = 0;
            break;
        }
    }
    for(let i = 0; i < 3; i ++) {
        sum += integers[i] ** 2;
    }
    if(x * x == sum) {
        return true;
    } else {
        return false;
    }
  }

优化

优化思路
还可以用 sort() 方法来给数组进行排序,比如让它的每个元素以从小到大的顺序排序,
然后再用  前两个元素的平方和  和  最后一个元素的平方  做比较
优化代码
function isPythagoreanTriple(integers) {
    var arr1 = integers.sort((a, b) => a-b);      
                // 相当于 var arr1 = integers.sort(function(a, b) { return a - b;})
    return arr1[0]**2 + arr1[1]**2 === arr1[2]**2;
}

心得

  • 这里直接用 Math.min(list) 是不行的(我一开始就是这样写的),上网查了才知道要在
    list前面加“...”, 第一次看到“...”的时候, 我的心情也是... , 看完才知道 “...”可以做
    扩展操作符将数组的展开,之后Math.min()方法才能生效
    
  • sort() 方法可以用于对数组的元素进行排序,默认情况是将数组元素转换为字符串,然后
    按ASC码进行排序,返回值是排好序的数组。
    sort() 方法如果有参数,则参数必须是一个函数,而且函数要接收两个参数,如果函数内返
    返回值是正数,则第一个参数排在第二个参数前面; 如果函数内返回值是负数, 则第二个参
    数排在第一个参数前面;如果返回值为0, 则按ASC码排序。
    
  • 此处最后返回代码   return arr1[0]**2 + arr1[1]**2 === arr1[2]**2;
    可换成     return (arr1[0]**2 + arr1[1]**2 == arr1[2]**2);    
    两者效果一样,都是返回布尔值
    

2. 数组的 CSV 表示形式(CSV representation of array)

描述:

创建一个返回二维数值数组的 CSV 表示形式的函数。
例: input:[[0, 1, 2, 3, 4],
            [10, 11, 12, 13, 14],
            [20, 21, 22, 23, 24]]
     
     ouput: '0, 1, 2, 3, 4\n'
            +'10, 11, 12, 13, 14\n'
            +'20, 21, 22, 23, 24'
        

思路

输入一个数组,返回其对应的CSV格式,首先想到可以用 join('\n') 方法将二维数组的一维数
组之间用换行的形式分隔,而一维数组之内以逗号形式分隔,然后再返回所得到的字符串。

代码

function toCsvText(array) {
     return array.join('\n'); 
 }

3. 查找列表的最大值和最小值(Find Maximum and Minimum Values of a List)

描述

你的任务是制作两个函数,接收整数列表作为输入,并分别返回该列表中的最大和最小数字。

思路

首先想到的是用冒泡法,将数组中的元素一个一个进行比较,大的或小的依次往上冒泡,但是效
率太慢,之后想到了 Math.min() 和 Math.max() 方法。

代码

const min = function(list) {           
    return Math.min(...list);               
}
const max = function(list) {              
    return Math.max(...list);
}

4. 你是个正方形!(You're a square!)

描述

你喜欢积木。你特别喜欢正方形的积木。而你更喜欢的是将它们排列成一个方形积木的正方形!
但是,有时您无法将它们排列成正方形。相反,你最终会得到一个普通的矩形!那些爆炸的东
西!如果你有办法知道,你目前是否在徒劳地工作......等!就是这样!你只需要检查你的积木
数量是否是一个*完美的正方形*。

给定一个整数,确定它是否是[平方数]:
在数学中,平方数或**完全**平方是一个整数,即整数的**平方**;换句话说,它是某个整数与
自身的乘积。是平方数则返回 true, 否则返回 false

思路

 直接用一个 for 循环遍历从 0 到 n 的整数,每次判断它的平方是否等于 n, 如果等于,则返回 ture,
 结束循环; 如果循环结束还没找到平方数,则返回false

代码

var isSquare = function(n) {
    for(let i = 0; i <= n; i++){
        if(i ** 2 == n) {
            return true;
        }
    }
    return false;
}

5. 3 或 5 的倍数(Multiples of 3 or 5)

描述

如果我们列出所有低于 10 的 3 或 5 倍数的自然数,我们得到 3、5、6 和 9。这些倍数的和是 23。
完成解决方案,使其返回传入数字下方所有 3 或 5 的倍数之和。 此外,如果数字为负数,则返回 0(对
于具有这些数字的语言)。
注意: 如果数字是 3 和 5倍数,则只计算一次。

问题思路(此思路代码结果可通过,但运行时间超额)

虽然代码结果可以通过, 但时间复杂度为 n平方。
从 0 到 n 遍历,每一次遍历中, 都算出该值相对于 3 和 5 的最大倍数 x 和 y,再从 1 到 x 和 y 再
遍历一遍,内层每次遍历中,比较判断 3 或 5 和内层遍历值的积  和  外层遍历值是否下相等。
这样说可能不太清晰,下面附上代码

问题代码

function solution(number){
  var sum = 0;
  flag:
  for(let i = 0; i < number; i ++) {
    let x = Math.floor(i/3);
    let y = Math.floor(i/5);
    for(let j = 1; j <= x; j ++) {
        if(i == 3 *j) {
            sum += i;
            continue flag;
        }
    }
    for(let j = 1; j <= y; j ++) {
        if(i == 5 * j) {
            sum += i;
        }
    }
  }
  return sum;
}

优化思路

可以试着把内部循环给去掉,让时间复杂度降下来, 倍数可以用求余的方法来判断(n % 3 == 0),
而且可以把 3 和 5 的判断放在一起,来优化代码

优化代码

function solution(number){
    var sum = 0;
    for(let i = 0; i < number; i ++) {
        if(i % 3 == 0 || i % 5 == 0) {
            sum += i;
        }
    }
    return sum;
  }

心得

  • 倍数的判断用求余运算符
    
  • 如果要从内层循环跳出外层循环,
       需要在外层for循环前面定义一个标记(标识符:)
                        如上述代码的 flag:
       再在内层循环中满足条件的执行语句中写上 break / continue 标记
                        如上述代码的 continue flag;