[プログラマー][JS]中秋の流量


中秋節の流量


質問:https://programmers.co.kr/learn/courses/30/lessons/17676
写真ソース:プログラマー
input: ["2016-09-15 00:00:00.000 3s"]
上記の図に示すように、[日時プロセス処理時間]は文字列に含まれて与えられます.1つの特定の期間内に最も多くのプロセス重複数を求める問題.
これはこの問題を解決する過程で問題を読み間違えて多くの時間を浪費した問題である.よくない習慣は、いつも問題をざっと見てから問題を解くことです.すぐ直さなければなりません.
実際の試験でこのような状況が発生したら...考えもしない.このことを教訓にして、本当に後で問題を全部把握してから始めましょう.
解決策はすべての状況の数を救った.KACAの問題なので、有効率チェックでどうするか、この方法で実現したら、効率性で発見されたら何とかして解決しようと思いますが、幸い効率性がありませんでした.

解決策


上にも言ったように、すべての状況が救われた.すべての場合の基準は、彼の最後の瞬間~1秒の間に、いくつかのプロセスを配列に入れ、配列の最値を返すことです.
  • line,parseTime():ログの開始時間と終了時間を取得するには、時間と処理時間を使用します.
  • 現在のログの後のログと比較する必要があるため、const restArr = arr.slice(idx + 1);を使用して後のログを並べ替えます.
  • 参照
  • restArrを使用して、各ログがmarkEndTime~markEndTime+1(秒)の間にあるかどうかを判断します.全部で3つの状況がある.現在のログの開始、終了をstart、endと呼びます.
  • start<=MarkEndTime<=end(MarkEndTimeがログ間にある場合)
  • start
  • LogはMarkEndTime、MarkEndTime+1の間にある.
    処理時間には、開始時間と終了時間が含まれます.この問題に集中して比較しなければならない.
  • 上記でtrueと判断した場合はcount++となり、すべてのログがループしている場合は答え配列に格納されます.
  • 出力アレイの最大値.
  • parseTime(time,process)


    時間(time)と処理時間(process)を入力し、開始、終了時間を秒に変換します.
    特に何もないので、開始時間も含めて、process-=0.001をした後、開始時間を求めました.시작시간 = 끝시간 - process

    code

    function solution(lines) {
      var answer = [];
    
      lines.forEach((line, idx, arr) => {
        const [date, time, process] = line.split(' ');
        const restArr = arr.slice(idx + 1);
        let [s, markEndTime] = parseTime(time, process);
        
        let count = 1;
        restArr.forEach((v) => {
          const [date, time, process] = v.split(' ');
          const [start, end] = parseTime(time, process);
          if (
            (markEndTime >= start && markEndTime <= end) ||
            (markEndTime + 1 > start && markEndTime + 1 < end) ||
            (start >= markEndTime && end < markEndTime + 1)
          )
            count++;
        });
        answer.push(count);
      });
    
      return Math.max(...answer);
    }
    
    function parseTime(time, process) {
      let [h, m, s] = time.split(':');
      const end = h * 3600 + m * 60 + s * 1;
      const processTime = process.slice(0, process.length - 1) * 1 - 0.001;
      const start = end - processTime;
      return [start, end];
    }

    の最後の部分


    問題を集中的に読むだけでは、長くかかる問題ではありません.
    しかし全ての場合検査した場合,時間的複雑度は比較的高くO(N^2)であった.実際にはたくさんのログがありますが、その時はどうすればいいのでしょうか...という考えがありました.
    最初の試行では、時間ベースで各ログに開始から終了まで0.001秒を加算し、オブジェクトのkey、value値として格納します.でも0.001秒で出てきた1.001+0.001=1.0099999999998なぜか聞いてみました.
    ほとんどのプログラミング言語(jsを含む)はIEEE 754規格に準拠しており、小数も2乗で表されているため、1/10は実際には0.1ではなく、0.100000000000 5551151257802158340541015625である.この事実を知った.
    出典:https://stackoverflow.com/questions/588004/is-floating-point-math-broken
    大まかな説明、詳しい説明は上のスタックオーバーフローリンクでご覧いただけます.めちゃくちゃな内容ですね.
    したがって,小数点を四捨五入するにはtoFixed()を用いる必要があることが分かった.
    本題に戻ると、上の方法は失敗した.そして、これも悪い方法です.メモリが食べられそうになりました.
    結論は本当にKACAではどんな方法でこの状況を把握するのか気になります!