首页
Preview

面试官:你已经工作了两年,怎么连这么简单的问题都回答不出来?

前言

最近,我的一个好朋友正在换工作。她选择成为一名程序员,非常出色和自信,但在最近的面试中遭遇了巨大的挫折。

面试官对她说:“你已经工作了两年,居然不能解决这两个问题?” 什么样的面试题会让面试官对某人如此粗鲁地说话呢?

1. Two Sum

提示: 这是 LeetCode 上的原题,点击 这里 查看。

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的两个整数。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

你可以按任意顺序返回答案。

示例 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

示例 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

示例 3:

Input: nums = [3,3], target = 6
Output: [0,1]

约束条件:

2 <= nums.length <= 104

-109 <= nums[i] <= 109

-109 <= target <= 109

只存在一个有效答案。

2.1. 使用两个“for”循环解决问题

当我的朋友看到这个问题时,她觉得自己很幸运,因为它似乎很容易。于是她马上写下了答案,等待面试官问下一个问题。

她的答案是:

const twoSum = (nums, target) => {
  const len = nums.length
  for (let i = 0; i < len; i++) {
    // j = i + 1, Because the same element cannot be repeated in the answer
    for (let j = i + 1; j < len ; j++) {
      // find the answer, return
      if (nums[ i] + nums[ j ] === target) {
        return [ i, j ]
      }
    }
  }
}

面试官对她的快速回答表示赞赏,但他对结果不是很满意,认为可能还有进一步的优化空间。

2.2. 使用“Map”解决问题

通常情况下,使用两个“for”循环来解决问题时,我们需要意识到算法的时间复杂度(O(n2))可能会得到优化。

实际上,我们可以使用一个“for”循环来完成,只要将加法变成减法,并将遍历的值存储在对象 sumCache 中即可。

例如:

输入:[2,7,11,15]

步骤1

Read 2 and "sumCache" is empty. Store 2 as the key and index 0 as the value in "sumCache"

步骤2

Read 7 and find that the target value is 9 - 7 = 2. 
If 2 exists in "sumCache", the 0 and 1 indexes will be returned directly

你觉得使用“Map”的方法简单明了,比 for 循环容易得多吗?

const twoSum = (nums, target) => {
  const len = nums.length
  const sumCache = {}
  for (let i = 0; i < len; i++) {
    const value = nums[ i ]
    // Calculate the diff
    const diff = target - value
    // If the diff already exists, return the corresponding index directly
    if (typeof sumCache[ diff ] !== 'undefined') {
      return [ sumCache[ diff ], i ]
    } else {
      // otherwise save the value and index
      sumCache[ value ] = i
    }
  }
}

太好了。我们得到了更好的结果。我们只使用了额外的 1.5M 空间,将时间减少了近一半,

3. 如何防止多次重复发送请求?

3.1. 问题信息

在工作中,通常需要仅发送一次请求,以防止用户重复点击。

请传入请求方法(执行后返回 Promise)并返回一个新方法。在连续触发时,仅发送一个请求。

示例:

function firstPromise () {
  // ...Please fill in here
}
let count = 1;
let promiseFunction = () =>
  new Promise(rs =>
    window.setTimeout(() => {
      rs(count++)
    })
  )
let firstFn = firstPromise(promiseFunction)
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1

3.2. 问题分析

与算法问题相比,这个问题相对容易,我们只需要利用闭包和“Promise”的特性即可完成。

function firstPromise(promiseFunction) {
  // Cache request instance
  let p = null
  return function (...args) {
    // If the requested instance already exists, it means that the request is in progress, return the instance directly without triggering a new request
    return p
      ? p
      // Otherwise send the request and set p to null at the end of the Promise, then the next request can be resent
      : (p = promiseFunction.apply(this, args).finally(() => (p = null)))
  };
}

测试:

let count = 1
let promiseFunction = () =>
  new Promise((rs) =>
    setTimeout(() => {
      rs(count++)
    }, 1000)
  )
let firstFn = firstPromise(promiseFunction)
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1
firstFn().then(console.log) // 1
setTimeout(() => {
  firstFn().then(console.log) // 2
  firstFn().then(console.log) // 2
  firstFn().then(console.log) // 2
}, 3000)

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
一个人玩
先找到想要的,然后出发

评论(0)

添加评论