Codewars刷题思路分享(JS)--------21~25

285 阅读6分钟

CodeWars 21~25

21. 分页助手(PaginationHelper)

描述

在这个练习中,您将加强您的页面对 fu 的掌握。您将完成 PaginationHelper 类,该类是一个实用程序类,用于查询与数组相关的分页信息。

该类旨在接受一个值数组和一个整数,该整数指示每个页面将允许多少项。集合/数组中包含的值类型不相关。

示例

var helper = new PaginationHelper(['a','b','c','d','e','f'], 4);

helper.pageCount(); //should == 2

helper.itemCount(); //should == 6

helper.pageItemCount(0); //should == 4

helper.pageItemCount(1); // last page - should == 2

helper.pageItemCount(2); // should == -1 since the page is invalid

// pageIndex takes an item index and returns the page that it belongs on

helper.pageIndex(5); //should == 1 (zero based index)

helper.pageIndex(2); //should == 0

helper.pageIndex(20); //should == -1

helper.pageIndex(-10); //should == -1

模板

class PaginationHelper {
constructor(collection, itemsPerPage) {
    
// 构造函数接受一个项数组和一个整数,该整数指示有多少项
// 项目适合单个页面
}
itemCount() {
// 返回总项目数
}
pageCount() {
// 返回页数
}
pageItemCount(pageIndex) {
// 返回当前页面上的项目数。page_index从零开始。
// 对于超出范围的pageIndex值,此方法应返回-1
}
pageIndex(itemIndex) {
// 确定项目所在的页面。从零开始的索引
// 对于超出范围的itemIndex值,此方法应返回-1
}

}

思路

在构造函数中声明一个 arr 接收存放项目数组, 声明一个 n 表示一页最多有多少项, 声明一个 sum 表示一共有多少页。

在 itemCount() 方法中,要返回总项目数,故直接返回 arr 的长度。

在 pageCount() 方法中,要返回页数, 直接返回 sum。

在 pageItemCount() 方法中,首先要判断检查输入的参数是否合法,若不合法,返回 -1, 若输入的是最后一页,则返回总项目数 减去 前面的页数乘以每页最多项目数,若输入的不是最后一页,则每一页都是满的,故返回每页最多项目数。

在 pageIndex() 方法中,首先判断检查输入的参数是否合法,若不合法,返回 -1,合法则返回该参数除以 n 的向下取整。

代码

class PaginationHelper {
	constructor(collection, itemsPerPage) {
	// 构造函数接受一个项数组和一个整数,该整数指示有多少项
	// 项目适合单个页面
        this.arr = collection;
        this.n = itemsPerPage;
        this.sum = Math.ceil(this.arr.length / this.n);
	}

	itemCount() {
        return this.arr.length;
		// 返回总项目数
	}
	pageCount() {
        return this.sum;
	// 返回页数
	}
	pageItemCount(pageIndex) {
        if(pageIndex + 1 > this.sum || pageIndex < 0) {
            return -1;
        } else if (pageIndex + 1 == this.sum) {
            return this.arr.length - (this.sum -1)*this.n;
        } else {
            return this.n;
        }
	// 返回当前页面上的项目数。page_index从零开始。
	// 对于超出范围的pageIndex值,此方法应返回-1
	}
	pageIndex(itemIndex) {
        if(itemIndex + 1 > this.arr.length || itemIndex < 0) {
            return -1;
        }
        return Math.floor(itemIndex / this.n);
	// 确定项目所在的页面。从零开始的索引
	// 对于超出范围的itemIndex值,此方法应返回-1
	}
}

22.数字总和

描述

给定两个整数a, b,可以是正数或负数,找到它们之间和包含它们的所有整数的总和并返回它。如果两个数字相等,则返回a 或者 b。

示例

(1, 0) --> 1 (1 + 0 = 1)

(1, 2) --> 3 (1 + 2 = 3)

(0, 1) --> 1 (0 + 1 = 1)

(1, 1) --> 1 (1 since both are same)

(-1, 0) --> -1 (-1 + 0const getSum = (a, b) => { let sum = 0; if(a > b) { let c = a; a = b; b = c; } for(let i = a; i <= b; i ++) { sum += i; } return sum; } = -1)

(-1, 2) --> 2 (-1 + 0 + 1 + 2 = 2)

思路一

首先要判断 a 和 b 的大小关系,若 a > b,则将 a 和 b 的值交换,确保 a 更小, b 更大。声明一个变量 sum = 0,表示总和。进入 for 循环,将 a 和 b 之间的值一次加到 sum 中。

代码一

const getSum = (a, b) => {
    let sum = 0;
    if(a > b) {
        let c = a;
        a = b;
        b = c;
    }
    for(let i = a; i <= b; i ++) {
        sum += i;
    }
    return sum;
}

思路二(优化思路)

求 a 到 b 的每一项相加和,可以用等差数列求和公式 n * (A1 + An) / 2, 故只需要求 n 的值, a 和 b 的大小问题可以用 Math.abs(a - b) 解决,所以 n 也就出来了。

代码二(优化代码)

const getSum = (a, b) => (Math.abs(a - b) + 1) * (a + b) / 2;

补充

代码一和代码二都用了箭头函数

如果箭头后面跟了大括号,则需要手动加 return 返回最终值,如代码一

如果箭头后面没有跟大括号,则会自动返回,不需要加 return, 如代码二

23.删除最小值

描述

给定一个整数数组,删除最小值。不要改变原始数组/列表。 如果有多个元素具有相同的值,请删除具有较低索引的元素。如果得到一个空数组/列表,则返回一个空数组/列表。不要更改剩余元素的顺序。

示例

Input: [1,2,3,4,5], output = [2,3,4,5]

Input: [5,3,2,1,4], output = [5,3,2,4]

Input: [2,2,1,2,1], output = [2,2,2,1]

思路

拿到先判断数组是否为空,可以从数组的长度判断。因为不能改变原始数组,需要通过深拷贝创建两个数组,第一个数组进行从小到大的排序,再获得排好序的数组的第一个元素,再用这个元素去第二个数组中查找它的第一个位置,获得位置后,最后再用splice返回删除元素的数组。

代码

const removeSmallest = (numbers) => {
    if(numbers.length === 0) {
        return [];
    }
    let arr1 = [...numbers];
    let arr2 = [...numbers];
    arr1.sort((a, b) => a - b);
    let n = numbers.indexOf(arr1[0]);
    arr2.splice(n, 1);
    return arr2;
}

补充

splice(index, num, char)

  • index 起始下标
  • num 删除的项目数
  • char 插入的项目(在起始下标之前)

24.猫年狗年

描述

我有一只猫和一只狗。

我和小猫/小狗同时得到了它们。那是几年前的事了。

  • 人类年>= 1
  • 人类年仅是整数
  • 第一年的猫年 15
  • 年的猫年 +9
  • 此后每年的猫年 +4
  • 一年的狗年 15
  • 第二年的狗年 +9
  • 此后每一年的狗年 +5

现在将各自的年龄返回为 [humanYears``catYears``dogYears]

var humanYearsCatYearsDogYears = function(humanYears) {

// Your code here!

return [0,0,0]; }

思路

前两年是没有规律的,故需要一个一个输出,第三年开始,猫每次加4,狗每次加5.

代码

var humanYearsCatYearsDogYears = function(humanYears) {
    if(humanYears == 1) {
        return [1, 15, 15];
    } else if( humanYears == 2) {
        return [2, 24, 24];
    } else {
        let catYears = 24 + (humanYears - 2) * 4;
        let dogYears = 24 + (humanYears - 2) * 5;
        return [humanYears, catYears, dogYears];
    }
  }
  

25. 最大值和最小值(Maximum and minimum)

描述

编写两个函数,分别返回传递给它们的参数的最大值和最小值。

  1. 函数将接受任意数量的参数
  2. 数字数组可以是任何深度
  3. 不能使用Math.max, Math.min, require
  4. 如果其中一个参数无法计算为数字,则返回 NaN

示例

max(1,2,3,4) ----------返回 4

max(1,2,3,['4']) - ----------返回 4;请注意,它返回了 4 而不是“4”

max(1,2,[3,4])-----------------返回 4

max(1,2,[3,[4]])--------------返回 4

max(1,2,[3,['4r']])----------返回 NaN

思路

首先需要把拿到的参数中的数字数组的深度给解出来,然后再将其变为数字类型或者NaN,如果没有NaN,再对参数数组进行排序(从大到小 或 从小到大),返回第一个参数,如果有则返回 NaN

代码

function max(){
     let arr = [...arguments].toString().split(",").map(Number);
    let a = arr.some((el) => Number.isNaN(el));
    if(!a) {    // 全是数字
        arr.sort((a, b) => b - a);
        return arr[0];
    }
    return NaN;
}

function min(){
    let arr = [...arguments].toString().split(",").map(Number);
    let a = arr.some((el) => Number.isNaN(el));
    if(!a) {    // 全是数字
        arr.sort((a, b) => a - b);
        return arr[0];
    }
    return NaN;
}

补充

some() 方法

  • some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

  • some() 方法会依次执行数组的每个元素:

    • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。

    • 如果没有满足条件的元素,则返回false。

  • some() 不会对空数组进行检测

  • some() 不会改变原始数组

isNaN() 函数

  • isNaN() 函数用于检查其参数是否是非数字值。

  • 如果参数值为 NaN 或字符串、对象、undefined等非数字值则返回 true, 否则返回 false。