FreeCodeCamp 初级算法题 - 数组排序并找出元素索引

数组排序并找出元素索引 (Where Do I belong)

题目链接

问题解释

  • 这个 function 接收两个参数,第一个参数为数组 arr,即为需要查找的原数组。第二个参数为数字 num,表示需要查询的数字。返回值为 numarr 排序后的索引 (即返回值为数字)
  • 比如接收的是 [1, 2, 3, 4]1.5,那么输出就是 1,如果接收的是 [20, 3, 5]19,那么输出应为 2

基本解法 - 排序后通过 indexOf 查找

思路提示

  • 题目的说明已经把思路提示的很明显了。我们只要先把这个元素添加进数组,然后排序。最后通过 indexOf 找出索引就可以了
  • 根据题目描述,这个思路应该是最容易想出来的。在其他解法中你还可以看到其他思路

参考链接

代码

1
2
3
4
5
6
7
8
9
function where(arr, num) {
arr.push(num);

arr.sort(function(a, b) {
return a - b;
});

return arr.indexOf(num);
}

解释

  • 这个解法主要是 sort 方法的运用。一开始可能不是很好理解。只要记住一点就行,sort 方法根据回调函数的返回值来排序。在上面的写法中,如果返回值小于 0 (即 a - b < 0),那么就把 a 排到前面
  • 因此,上面写法的意思就是,把数组按照从小到大的顺序来排序。可以这样去记忆,由于 ab 就是数组中的相邻两个元素,既然返回值是 a - b,那么就意味着 a < b,所以是从小到大。如果返回值是 b - a,也就意味着是 b < a,也就是从大到小排序
  • 从小到大排序之后,我们通过 indexOf 来找 num 在其中的位置就可以了
  • 如果你不是刚接触编程,可以去了解一下排序的原理 (如果只是从 FCC 开始学编程,那这一步先暂时跳过吧),实现排序的算法有很多种,常见的快速排序、冒泡排序、桶排序,以及归并排序、插入排序、基数排序等等,有兴趣的话可以研究一下这些常用的,然后用 JavaScript 来实现每一个,相信你会有很大收获
  • 如果你对源码感兴趣,比如你想知道 Chrome 浏览器的 sort 是如何实现的,请看这个链接。这部分是 V8 引擎源码,可以看到,当数组长度小于 22 时,用的是插入排序,否则就用快速排序 (确切地说,使用的是快速排序中的 in-place quicksort)

优化 - 循环

思路提示

  • 循环也是没问题的。思路在于,我们遍历数组,统计出其中比 num 小的元素数量
  • 举个例子,如果数组中有 3 个数比 num 小,那么 num 得排在第 4 位,因此这时候 numindex 就为 3
  • 所以,得出结论,如果有 n 个数比 num 小,那我们直接返回 n 就可以了
  • 值得注意的是,如果元素相等需要怎么处理?可以想一下,如果传入的 numarr 中已经存在,那我们就不用关心把 num 放在哪,因为排序后,不论放在哪里都是连续的两个数,我们只要找到第一个数的 index 就可以了
  • 因此,同样适用于上面的结论:”如果有 n 个数比 num 小,那我们直接返回 n 就可以了”。只要统计的时候,不统计相等的,只统计比 num 小的就行

代码

1
2
3
4
5
6
7
8
9
10
11
function where(arr, num) {
var count = 0;

for (var i = 0; i < arr.length; i++) {
if (arr[i] < num) {
count += 1;
}
}

return count;
}

解释

  • 之所以说这样是优化,如果你听说过时间复杂度,应该就明白为什么了。插入排序的时间复杂度是 n 平方,快速排序期望是 n*log(n),最坏是 n 平方。而用 for 循环,时间复杂度是 n
  • 如果不明白这一点,也不影响做题。以上的两种方法都是可行而且可以接受的

一行搞定 - 使用 filter

思路提示

  • 首先,请先理解上一个答案中提到的思路。也就是,统计出数组中有多少个元素比 num 小。具体的分析请看上一个解法中提到的
  • 那么,如何在这个情景下使用 filter 呢?可以这么考虑一下,既然我们想要知道究竟有多少个元素比 num 小,那我们只要根据这个条件过滤数组,然后用 .length 获取数组长度,是不是就能得出有多少个元素比 num 小了呢?
  • 如果你还没想明白,请再读三遍上面这句话。或者,自己想一个实际的例子,带入到上面这句话验证一下

参考链接

代码

ES5

1
2
3
4
5
function where(arr, num) {
return arr.filter(function (e) {
return e < num;
}).length;
}

ES6

1
2
3
function where(arr, num) {
return arr.filter(e => e < num).length;
}
文章目录
  1. 1. 数组排序并找出元素索引 (Where Do I belong)
    1. 1.1. 题目链接
    2. 1.2. 问题解释
  2. 2. 基本解法 - 排序后通过 indexOf 查找
    1. 2.1. 思路提示
    2. 2.2. 参考链接
    3. 2.3. 代码
    4. 2.4. 解释
  3. 3. 优化 - 循环
    1. 3.1. 思路提示
    2. 3.2. 代码
    3. 3.3. 解释
  4. 4. 一行搞定 - 使用 filter
    1. 4.1. 思路提示
    2. 4.2. 参考链接
    3. 4.3. 代码
      1. 4.3.1. ES5
      2. 4.3.2. ES6
,