记一个css面试题和一个js算法题

414 阅读4分钟

近日在Experian去面了一个angular前端岗位,有两道题觉得比较有意思而且比较常考,所以拖出来说说:

CSS

官:你怎么居中一个文本或块?

我:项目里大部分情况下直接用Bootstrap的.text-center即可居中文本,新的v4还提供了.align-items-center和.justify-content-center配合栅格系统即可解决

官:excellent!(鄙视地)那不让你用第三方库呢,如下我html里只有个div,你css居一下?

<div class="target">
</div>

我:通常网页不会直接垂直居中的,左右居中的话常见的方式就是加个margin: 0 auto;当然这个div得有宽度才行。

我:要全部居中可以把这个块的位置设置成绝对的,然后移动到父节点的水平垂直一半的位置上。因为自己也有宽高,最后把自己往上和左移动自己长度的一半,这里用translate就行了。

div {
    background: red;
    width: 100px;
    height: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

官:嗯~!你有听说过flex吗,能不能用这个做?

我:新版的bootstrap就是基于flex布局的,它提供了start center end between around 5 个基础位置,方便排版。

<div class="container">
    <div class="target"></div></div>

我:首先,我们需要个容器,应题目要求这个容器得跟html body一样宽高,把它的display设置为flex即可对它的子节点进行布局了,水平用justify-content,垂直用align-items

.container {
    display: flex;
    height: 100%;
    align-items: center;
    justify-content: center;
}

.target {
    background: red;
    width: 100px;
    height: 100px;
}

html, body {
    height: 100%;
    margin: 0; // body默认8px的margin,不重制的话会多出来一个滚动条!
}

JS

官:给你一个仅包含数字的无序数组和一个数字(和),找出一对数字使得他们的和是这个提供的数字。i.e. [1,2,3], 3 => 1,2

我:直接俩循环遍历数组,每次相加对比和,如下

function findPairs(arr, sum) {	for (let i = 0; i < arr.length - 1; i++) {
		for (let j = i + 1; j < arr.length -1; j++) {
			if (arr[i] + arr[j] === sum) {
				return {first: arr[i], second: arr[j]};
			}
		}
	}
    
        return null;
}

// test
console.log(alg([1,2,3], 3))

官:写得很快嘛(奸笑),分析下时间复杂度,兄dei。

我:两次循环所以O(n^2)。

官:我们经常要处理几百万千万的数据,你觉得你对你的方法满意么?

我:。。。

官:想想如果把数组先弄成有序的,再去找会不会快些?

我:如果mergeSort的话,首先要花个nlogn时间,然后利用sum的大小属性一遍循环即可出结果。定义左右两指针,分别从前往后扫,和从后往前扫,如果两指针的数字加起来小于sum,那么表示我需要找比这个和大一点的数,因为是排好序的,所以这个数刚好就是左指针下一个数;同理如果和大于sum就要减小一点,于是移动右指针。O(nlogn)

function findPairs(arr, sum) {
    arr = mergeSort(arr);
    
    const left = 0;
    const right = arr.length - 1;

    while (left < right) {
        if (arr[left] + arr[right] < sum) {
            l++;
        } if (arr[left] + arr[right] > sum) {
            right--;
        } else {
            return {first: arr[l], second: arr[right]};
        }    }

    return null;
}

官:还能不能更快,我们可是有超多人的信用记录的。

我:(你真的打算要前端去遍历所有人的信用记录?摆明了为难我胖虎)

官:如果把数字存在哈希表里,你每次取值判断就不需要循环了,非常快

我:可是js没有原生的哈希表实现啊,但是js的Map或者object机制非常适合这种情况。对数组做一次遍历,遇到每个元素时做减法,如果减出来的值不在map里面,我就把减数放进这个map,这样下次你遇到一个减出来的结果等于这个值的数字时,即匹配成功,直接输出。因为每次做判断时只是取引用,不会遍历所以很快 O(n)

function findPairs(arr, sum) {
    const tempMap = {}; // 或者new Map

    for (let i = 0; i < arr.length - 1; i++) {
        let temp = sum - arr[i];
        if (tempMap[temp]) {
            return {first: temp, second: arr[i]};
        }
        tempMap[arr[i]] = arr[i];
    }

    return null;
}