937. 重新排列日志文件
解法一:二分法排序 + 自定义判断逻辑
1、先遍历数组,分出 字母 和 数字 两种日志。
2、使用二分法排序 字母日志,判断大小的逻辑要根据题目说明来写。
3、合并返回两个数组
/**
* @param {string[]} logs
* @return {string[]}
*/
var reorderLogFiles = function (logs) {
const digList = [];
const letList = [];
for (const i of logs) {
if (!isNaN(Number(i.split(" ").splice(1)[0]))) {
digList.push(i);
} else {
letList.push({
originVal: i,
tag: i.split(" ")[0],
contentList: i.split(" ").slice(1),
});
}
}
const letSortList = binary(letList).map(item => item.originVal);
return letSortList.concat(digList);
};
function binary(list) {
if (list.length === 0) {
return [];
} else if (list.length === 1) {
return list;
}
const left = [];
const right = [];
const flag = list[0].contentList;
for (let i = 1; i < list.length; i++) {
const conList = list[i].contentList;
if (conList.join(" ") !== flag.join(" ")) {
let index = 0;
while (true) {
if (conList[index] < flag[index] || index === conList.length) {
left.push(list[i]);
break;
} else if (conList[index] > flag[index] || index === flag.length) {
right.push(list[i]);
break;
} else {
index++;
}
}
} else {
if (list[i].tag < list[0].tag) {
left.push(list[i]);
} else {
right.push(list[i]);
}
}
}
return binary(left).concat([list[0]]).concat(binary(right));
}
解法二: sort 方法排序
1、先遍历数组,分出 字母 和 数字 两种日志。
2、使用数组的 sort 方法排序
3、合并返回两个数组
/**
* @param {string[]} logs
* @return {string[]}
*/
var reorderLogFiles = function (logs) {
const digList = [];
const letList = [];
for (const i of logs) {
if (!isNaN(Number(i.split(" ").splice(1)[0]))) {
digList.push(i);
} else {
letList.push({
originVal: i,
tag: i.split(" ")[0],
content: i.split(" ").slice(1).join(" "),
});
}
}
const letSortList = letList
.sort((a, b) => {
if (a.content !== b.content) {
return a.content < b.content ? -1 : 1;
} else {
return a.tag < b.tag ? -1 : 1;
}
})
.map(item => item.originVal);
return letSortList.concat(digList);
};
:::info
字符串比较
上面字符串比较我是直接比较大小的,比如 'a' < 'b'
,这是允许的,这个表达式的值为 true
,因为:
"a".charCodeAt(); // 97
"b".charCodeAt(); // 98
所以非数字字符串比较大小比较的其实是他们 ASCII 码的大小,而且是按顺序比较的,先比较第一位,如果能比较出大小,那结果就是最终结果,如果相等就比较第二位,以此类推。
参考:https://www.fly63.com/article/detial/4071
sort 方法
语法:
arr.sort([compareFunction]);
如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的 Unicode 位点进行排序。例如 “Banana” 会被排列到 “cherry” 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在 Unicode 顺序上 “80” 要比 “9” 要靠前。
如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
- 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
- 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
- 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
- compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
以上内容全部从 MDN - Array.prototype.sort() 复制 :::