fezaoduke / fe-practice-hard

晚练课
69 stars 6 forks source link

第 101 期(算法-排序):根据内容排序数组 #104

Open wingmeng opened 5 years ago

wingmeng commented 5 years ago

看到一道挺有意思的大厂面试题:

一个数组中保存有红、黄、蓝三种颜色的球,且每种球的个数不相等、顺序不一致,请为该数组排序。使得排序后数组中球的顺序为:黄、红、蓝。 例如:红蓝蓝黄红黄蓝红红黄红,排序后为:黄黄黄红红红红红蓝蓝蓝。

测试用例:

const balls = ['红', '蓝', '蓝', '黄', '红', '黄', '蓝', '红', '红', '黄', '红'];

思路:

上面的题目,实质上是将颜色相同的球归类到一起,然后按照“黄、红、蓝”的顺序进行排列。很容易就能想到用数组的 sort() 方法,但直接 sort() 的话,只能将相同颜色的球归类到一起,而无法定义顺序。这时就需要在 sort() 方法的比较函数里做些文章了,这个函数默认有 2 个参数,代表当前数组项的两个值,通过返回一个用于说明这两个值相对顺序的数字来决定排序顺序,假设这两个参数分别为 a 和 b,则有:

但我们发现数组项都是汉字,无法进行大小判断,怎么办呢?如果我们建立一个“映射表”,将不同数组项映射为对应的数字,是不是就可以判断大小了?同时我们可以利用数字大小来控制排序顺序,如此一来,就可以实现我们的预期目的了。

参考代码:

// 定义一个映射表,将不同颜色的球映射为数字,数字越小则排序越靠前
const sortRule = { '黄': 1, '红': 2, '蓝': 3 };

balls.sort((a, b) => sortRule[a] - sortRule[b]);

上面是用了 Hash 表,还可以用 Map 表来实现:

const sortRule = new Map([
  ['黄', 1], ['红', 2], ['蓝', 3]
]);

balls.sort((a, b) => sortRule.get(a) - sortRule.get(b));