前端面试题(两个升序数组合并为一个升序数组)

给定两个数组a和b,值为别为[1,3,5,7]和[2,4,6,8],怎么才能将它们变成c,值为[1,2,3,4,5,6,7,8]?

前提不能把a和b合并之后再排序,并且采用最优算法让循环执行的次数最少。

这道题是近来比较火的算法题之一,我在58以及区块链的一家公司都遇到过,而且不仅前端,也可以作为py,java面试题。

在算法当中,优化就是尽量避免无效的计算。

举个例子,我们经常使用循环来创建一系列的元素,并添加到页面中,这样的案例数不胜数。

// 第一种方式
function createGoodsList(num) {
    var i = 0, array = [];
    for( ; i<num; i++) {
        array.push('<li>' + (i+1) + '</li>')
    }
    return array
}
document.getElementById('goods_wraper').innerHTML = createGoodsList(10).join('')
// 第二种方式
function createGoodsList(num){
    var i = 0, str = '';
    for( ; i<num; i++){
        str += '<li>' + (i+1) + '</li>'
    }
    return str
}
document.getElementById('goods_wraper').innerHTML = createGoodsList(10)
// 第三种方式
function createGoodsList(parent,num){
    var i = 0
    for( ; i<num; i++){
        var liElement = document.createElement('li')
            liElement.innerText = i + 1
        parent.appendChild(liElement)
    }
}
createGoodsList(document.getElementById('goods_wraper'),10)

上面的方法,第一种优于第二种,第二种优于第三种。第二种减少了频繁的DOM操作,第一种减少了中间变量的产生,避免了一些无效的计算。

这是因为早期浏览器中没有对于 ‘+’ 运算符的优化,由于String类型是不可变的,所以要创建中间值来存储 ‘+’ 连接的结果,频繁地创建和销毁字符串导制程序运行性能异常的差。

回到我们的题目中。

我们看a和b,都是已经给定的升序数组,既然不能合并a和b,要达到最优的算法过程,必然要利用给定的升序规则,
即针对a和b进行循环比对相同索引的值的大小,将值小者放到c中,然后值大者与值小者下一位进行比对,
假设a与b的长度是不等的,我们要设置两个下标来对应a和b各自的索引,
并且在比对以后,要针对长度较大的数组额外写一个循环,将没有参加比对的值放到c中
看代码吧

var a = [1,3,5,7,9]
var b = [2,4,6,8]
var i = j = 0, c = [], a_length = a.length, b_length = b.length
while(i<a_length && j<b_length){
    if(b[j] > a[i]){
        c.push(a[i])
        i++
    }else{
        c.push(b[j])
        j++
    }
}
while(i<a_length){
    c.push(a[i])
    i++
}
while(j<b_length){
    c.push(b[j])
    j++
}
console.log(c)

虽然写完了,但是仔细想一下上面的代码,因为我们并不知道a和b哪个数组长度长一点,才会多写一个循环,那么我们有没有办法把三个循环的写法(真正执行的只有两个)简化一下呢?

当然是可以的,我们只需要判断一下在读取数组中的值得时候,这个值是否存在

var a = [1,3,5,7,9]
var b = [2,4,6,8]

var i = j = 0, c = [], a_length = a.length, b_length = b.length

while(i<a_length || j<b_length){
    if(b[j] > a[i] && a[i] || !b[j]){
        c.push(a[i])
        i++
    }else if(b[j] <= a[i] && b[j] || !a[i]){
        c.push(b[j])
        j++
    }
}

猜你喜欢

转载自blog.csdn.net/zhai_865327/article/details/83865778