“这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战”
题目:给出两个已排序的数组,要求将两个数组合并为一个排序的数组。
// 输入
let a = [1, 3, 5, 7, 9]
let b = [2, 4, 6, 8, 10]
// 输出
let c = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
要想将两个数组合并为一个数组我们最容易想到的是 concat 方法,关于排序我们能想到 sort 方法,于是乎就写出了下面的代码:
function mergeArray(first, sec) {
return first.concat(sec).sort((a, b) => a - b)
}
let a = [1, 3, 5, 7, 9]
let b = [2, 4, 6, 8, 10]
let c = mergeArray(a, b)
console.log(c)
这样写我不能说你错,只能说不对。我们来分析一下原因在哪里,首先合并数组需要处理数组的每一项,然后排序数组又需要处理数组的每一项,这样下来复杂度就变成O(NlogN)。
由于提供是的已经排好序的数组,所以我们可以利用这个特性判断每次插入的位置,在下面代码中,使用了两个指针,i 指针标记第一个数组的位置,j 指针标记第二个数组的位置,k 表示插入数组的下标索引位置。我们先遍历长度较短的数组项,最后再处理剩下的数组项。
function mergeArray(first, sec) {
var temp = []
var t = 0
var i = 0
var j = 0
var k
// 取较短的数组开始loop
var mid = (first.length <= sec.length) ? first.length - 1 : sec.length - 1
while (i <= mid && j <= mid) {
//关键的逻辑在于这行
k = (first[i] < sec[j]) ? first[i++] : sec[j++]
//过滤重复元素
if (t > 0 && k == temp[t - 1]) {
continue
}
temp[t++] = k
}
// 将first数组中剩余的元素追加到temp
while (i <= first.length - 1) {
k = first[i++]
if (t > 0 && k == temp[t - 1]) continue
temp[t++] = k
}
// 将sec数组中剩余的元素追加到temp
while (j <= sec.length - 1) {
k = sec[j++]
if (t > 0 && k == temp[t - 1]) continue
temp[t++] = k
}
return temp
}
核心思路就是如何处理每次插入的位置,首先我们得先比较相同索引位置谁的值小,将较小的值添加到数组中,添加之后索引往后移动,新数组的下标也要跟着移动。复杂度就变成O(N)。
关于双指针的算法题在面试中也经常被问到,所以在面试之前还是有必要复习一下。下面再看一道常见的算法,判断回文字符串的题目。
1. 131 是回文,从前往后是131,从后往前是131,131等于131
2. 123 不是回文,从前往后是123,从后往前是321,123不等于321
现在我们已经知道了什么是回文字符串,也就是正面和反面得到的字符串是一样的。关于这个题目很多人会想到先将字符串 split 变成数组,然后将数组 reverse 翻转,最后将数组 join 变成字符串。
function isPaindrome (s) {
return s === s.split('').reverse().join('')
}
多次使用数组的API调用,增加了算法的复杂度,接下来使用双指针来判断是否回文字符串,通过遍历一次即可完成,思路也非常的简单。
// 双指针
function isPaindrome(s) {
if (!s) {
return true
}
let left = 0
let right = s.length - 1
while (left < right) {
if (s[left] !== s[right]) {
return false
}
left++
right--
}
return true
}
console.log(isPaindrome('abba'))
其实随着刷题的深入,我发现刷题其实就是分为两步:
- 第一步有思路,即知道用哪种姿势怎么解题;
- 第二步是实现,即将你的思路转化为代码。
算法题刷多了,你就会发现,最后其实在你脑子里记住的不是实现这道题的代码,而是解这道题的思路。说白了就是多刷题,见多才能识广。
一道题有了思路,其实这道题的 90% 你已经解决了,把它实现出来按理来说就是自然而然的事儿了。