算法题分享之导弹拦截

207 阅读3分钟

前言

昨日朋友分享了一道题目给我,叫我别问为什么,直接做(为了验证她一个猜想),咱也没多问,然后就有了下面的事情。

一道简单的题目

题目是这样的:

【场景】
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦截系统有一个缺陷:
星然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,由于该系统还在试用阶段,所以一套系统有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。
【输入】

n颗依次飞来的高度(1≤n≤1000)。

【输出】

要拦截所有导弹最小配备的系统数k。

【输入样例】

389 207 155 300 299 170 158 65

【输出样例】

2

误区

初始读题目,觉得很简单,两分钟写出了代码,如下:

function compute(arr) {
  if (!arr.length || arr.length > 1000) {
     return 0;
  }
  let result = 1;
  let i = 0;
  while(arr[i++]) {
      if (arr[i] > arr[i - 1]) {
        result++;
      }
  }
  return result;
}
// 输入:[100, 90, 96, 62, 86],  计算结果: 3
console.log(`输入:[100, 90, 96, 62, 86],  计算结果:`, compute([100, 90, 96, 62, 86]))

可能大多数人看到这个题目给出的答案都和我一样,但不得不说我们都陷入了一个误区。这道题还有另一个答案:

function compute(arr) {
  if (!arr.length || arr.length > 1000) {
    return 0;
  }
  let result = 1;
  let i = 0;
  let currentEndHeight = 0;
  while(arr[i++]) {
    if (arr[i] > arr[i - 1] && currentEndHeight <= arr[i]) {
      currentEndHeight = currentEndHeight > arr[i - 1] ? currentEndHeight : arr[i - 1]
      result++;
    }
  }
  return result;
}
// 输入:[100, 90, 96, 62, 86],  计算结果: 2
console.log(`输入:[100, 90, 96, 62, 86],  计算结果:`, compute([100, 90, 96, 62, 86]))

思考方式不同,答案也许会有差别。

复盘

脱离了校园的学术环境,我们的思维也产生了一些潜移默化的变化,习惯了工作的按部就班,习惯了任务看板的1、2和3。

想法一

题目没有把场景描述清楚,给出的示例里面没有跳跃攻击(让人理所当然的把输入值分段处理),这是题目的问题。

想法二

题目给出了以最少资源达到目的的要求,就是要让我们自己去思考最优解,给出的示例本身没有任何问题,也是符合场景的,错的只是我们的一成不变。

结论和思考

由于工作环境的熏陶,我们总是从需求的角度出发,客户需要把各个需求都描述清楚,包括各种特殊场景、边界情况,完成了客户列出的所有要求,就算圆满完成任务。在这种环境下,我们也越来越"懒","懒"得去想,"懒"得去思考,"懒"得去做一些想做的事。毕竟,人生已是如此的艰难。

在后来的某个瞬间,我突然回想到了高考数学考场上自己为了解一道题写了大半张草稿纸的场景,高中那段时间,大概是我最努力的时光吧。