前端刷華為機考24題

我的窮舉法這次不僅內(nèi)存占用超出了,而且還超出了瀏覽器所能承受的最大限制,報錯了

下面的是我把 Java 解法改成 JS 的

     (function () {
       const n = 8;
       let arr = `186 186 150 200 160 130 197 200`.split(" ");

       let left = [],
         right = [];
       left[0] = 1;
       right[n - 1] = 1;
       for (let i = 0; i < n; i++) {
         left[i] = 1;
         for (let j = 0; j < i; j++) {
           if (arr[i] > arr[j]) {
             left[i] = Math.max(left[j] + 1, left[i]);
           }
         }
       }

       for (let i = n - 1; i >= 0; i--) {
         right[i] = 1;
         for (let j = n - 1; j > i; j--) {
           if (arr[i] > arr[j]) {
             right[i] = Math.max(right[i], right[j] + 1);
           }
         }
       }


       let result = [];
       for (let i = 0; i < n; i++) {
         result[i] = left[i] + right[i] - 1;
       }


       let max = 1;
       for (let i = 0; i < n; i++) {
         max = Math.max(result[i], max);
       }
       console.log(n - max);
     })();

left數(shù)組為[1, 1, 1, 2, 2, 1, 3, 4],存儲遞增序列長度

186 前面沒有算一個
186 前面沒有算一個
150 前面沒有算一個
200 前面有 186 算兩個
160 前面有 150 算一個
130 前面沒有算一個
197 前面有 150 160 算三個
200 前面有 150 160 197 算 4 個

right 數(shù)組為 [3, 3, 2, 3, 2, 1, 1, 1]存儲遞減序列長度

186 后面有 150 130 算三個
186 后面有 150 130 算三個
150 后面有 130 算兩個
200 后面有 160 130 算三個
160 后面有 130 算兩個
130 后面沒有算一個
197 后面沒有算一個
200 后面沒有算一個

leftright對應(yīng)索引相加在減一晴裹,因為都算了自身

result[3, 3, 2, 4, 3, 1, 3, 4]

那么result數(shù)組就是對應(yīng)索引下符合從左到右遞增且從右到左遞減的這種規(guī)律的序列長度了田盈,總?cè)藬?shù)減去即可

注意 Math.max(left[j] + 1, left[i]); 因為是雙重循環(huán),left[i]在發(fā)生left[j] + 1 < left[i]時尿这,left[i]的值必然不是 1 了簇抵,當這種情況發(fā)生,說前面已經(jīng)有更長的了妻味,有left[j]的序列要比目前最長的短

基于上述正压,可以給出知道哪些索引被移除的代碼

    (function () {
      const n = 8;
      let arr = `147 186 186 150 200 160 130 197 200`.split(" ");

      let left = [],
        right = [],
        leftInfos = {},
        rightInfos = {};
      left[0] = 1;
      right[n - 1] = 1;
      for (let i = 0; i < n; i++) {
        left[i] = 1;
        leftInfos[i] = [];
        for (let j = 0; j < i; j++) {
          leftInfos[i][j] = [];
          if (arr[i] > arr[j]) {
            leftInfos[i][j].push(...(leftInfos[j][j - 1] || []), j);

            left[i] = Math.max(left[j] + 1, left[i]);
          } else {
            leftInfos[i][j] = [...(leftInfos[i][j - 1] || [])];
          }
        }
      }

      console.log(leftInfos);

      for (let i = n - 1; i >= 0; i--) {
        right[i] = 1;
        rightInfos[i] = [];
        for (let j = n - 1; j > i; j--) {
          rightInfos[i][j] = [];

          if (arr[i] > arr[j]) {
            rightInfos[i][j].push(j, ...(rightInfos[j][j + 1] || []));

            right[i] = Math.max(right[i], right[j] + 1);
          } else {
            rightInfos[i][j] = [...(right[i][j + 1] || [])];
          }
        }
      }
      console.log(rightInfos);

      let result = [];
      for (let i = 0; i < n; i++) {
        result[i] = left[i] + right[i] - 1;
      }

      let max = 1;
      for (let i = 0; i < n; i++) {
        max = Math.max(result[i], max);
      }
      console.log(n - max);
    })();

因為最大長度為 5 是在索引為 4 的地方,此時leftInfos[4]的值為[[0],[0,1],[0,2],[0,3]],分別代表 147 小于 200责球,147 小于 200 且 186 小于 200,147 小于 200 且 186 小于 200焦履,147 小于 200 且 150 小于 200。
此時rightInfos[4]的值為[[5,6],[6],[7]],再次組合就知道索引雏逾,可能的情況有

0,1,4,5,6
0,2,4,5,6
0,3,4,5,6

下面是我窮舉的解法嘉裤,其實對于前端來將,這已經(jīng)能夠解決大部分場景了栖博。

124
16 103 132 23 211 75 155 82 32 48 79 183 13 91 51 172 109 102 189 121 12 120 116 133 79 120 116 208 47 110 65 187 69 143 140 173 203 35 184 49 245 50 179 63 204 34 218 11 205 100 90 19 145 203 203 215 72 108 58 198 95 116 125 235 156 133 220 236 125 29 235 170 130 165 155 54 127 128 204 62 59 226 233 245 46 3 14 108 37 94 52 97 159 190 143 67 24 204 39 222 245 233 11 80 166 39 224 12 38 13 85 21 47 25 180 219 140 201 11 42 110 209 77 136

如上數(shù)據(jù)說是內(nèi)存超了屑宠,我把代碼到本地執(zhí)行,已經(jīng)報錯了仇让。

const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
let lineList = [];
rl.on("line", function (line) {
    lineList.push(line);
});

function combination(S, k) {
  if (k === 0 || S.length === k) {
    return [S.slice(0, k)];
  }
  const [first, ...others] = S;
  let r = [];
  r = r.concat(combination(others, k - 1).map((c) => [first, ...c]));
  r = r.concat(combination(others, k));
  return r;
}
rl.on("close", function (line) {
    const heightList = lineList[1].split(" ");
    let num = 0,
        resultList = [[]],
        indexList = Array(heightList.length)
          .fill(1)
          .map((item, i) => i);;

    for (let i = 0; i < resultList.length; i++) {
        let dataList = [...heightList];
        resultList[i].forEach((el, index) => {
            dataList.splice(el - index, 1);
        });

        let middleIndex = 0;
        for (let j = 0; j < dataList.length - 1; j++) {
            if (dataList[j + 1] > dataList[j]) {
                middleIndex = j + 1;
            } else {
                break;
            }
        }

        let lastIndex = 0;

        if (middleIndex != 0 && middleIndex != dataList.length - 1) {
            for (let h = middleIndex; h < dataList.length - 1; h++) {
                if (dataList[h + 1] < dataList[h]) {
                    lastIndex = h;
                } else {
                    break;
                }
            }
        }

        if (lastIndex == dataList.length - 2) {
            break;
        }

        if (i === resultList.length - 1) {
            i = -1;
            num++
            resultList = combination(indexList,num);


        }
    }

    console.log(num);
});

combination(['A'典奉,'B','C'],2)能夠得到所有兩兩組合,這已經(jīng)是優(yōu)化版本丧叽,就是先一個都不移除卫玖,看符不符合,在移除一個踊淳、兩個假瞬,之前的版本因為要借助一個的形成兩個的組合,所以要都保留迂尝,但數(shù)據(jù)夠大時脱茉,對內(nèi)存的占用的減少依舊杯水車薪。

一次算出所有組合再按照個數(shù)排序

      Array(count)
        .fill(1)
        .map((item, i) => i)
        .forEach((item) => {
          let list = [[item]];
          resultList.forEach((arr) => {
            list.push([...arr, item]);
          });

          resultList.push(...list);
        });

      resultList.sort((a, b) => a.length - b.length);

借著就是判斷移除好的數(shù)組符不符合要求了垄开。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琴许,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子溉躲,更是在濱河造成了極大的恐慌榜田,老刑警劉巖寸认,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異串慰,居然都是意外死亡偏塞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門邦鲫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灸叼,“玉大人,你說我怎么就攤上這事庆捺」沤瘢” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵滔以,是天一觀的道長捉腥。 經(jīng)常有香客問我,道長你画,這世上最難降的妖魔是什么抵碟? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮坏匪,結(jié)果婚禮上拟逮,老公的妹妹穿的比我還像新娘。我一直安慰自己适滓,他們只是感情好敦迄,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凭迹,像睡著了一般罚屋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗅绸,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天脾猛,我揣著相機與錄音,去河邊找鬼朽砰。 笑死尖滚,一個胖子當著我的面吹牛喉刘,可吹牛的內(nèi)容都是我干的瞧柔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼睦裳,長吁一口氣:“原來是場噩夢啊……” “哼造锅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起廉邑,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哥蔚,失蹤者是張志新(化名)和其女友劉穎倒谷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糙箍,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡渤愁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了深夯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抖格。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖咕晋,靈堂內(nèi)的尸體忽然破棺而出雹拄,到底是詐尸還是另有隱情,我是刑警寧澤掌呜,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布滓玖,位于F島的核電站,受9級特大地震影響质蕉,放射性物質(zhì)發(fā)生泄漏势篡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一模暗、第九天 我趴在偏房一處隱蔽的房頂上張望殊霞。 院中可真熱鬧,春花似錦汰蓉、人聲如沸绷蹲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祝钢。三九已至,卻和暖如春若厚,著一層夾襖步出監(jiān)牢的瞬間拦英,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工测秸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疤估,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓霎冯,卻偏偏與公主長得像铃拇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沈撞,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容