Codewars - ピークを選択する

Patricia Arquette
リリース: 2025-01-11 06:59:43
オリジナル
673 人が閲覧しました

ご挨拶

Codewars - Pick peaks

このシリーズでは、Codewars の課題と私の思考プロセスを投稿しています。私は可能な限り JS と Node 18 を使用しています。明確にするために、私はそれらを公正に使用しています。

お休みしていましたが、今は戻ってきました。ただし、解決策をここに投稿せずにいくつかの課題を実行しました。簡単なチャレンジに挑戦してみましょう。

ピークを摘むのは楽しいものです。数学的定義に従って極大値を見つける必要があります。 GFG より:

数学的には、f (a) ≥ f (a -h) および f (a) ≥ f (a h) ここで、h > 0 の場合、a は極大点と呼ばれます。

本質的には、どの値が最も近い値よりも大きいかを確認する必要があります。近傍が欠落している場合、それが極大値であるかどうかを検証できません。 したがって、配列の境界線はチェックしません

次のソリューションは最適化されていません。それは 1 パスである必要があります。それに、休憩を使わずに続けるように教えられました。しかし、それは仕事をします。

まずルールを設定します:

  • 配列が空の場合は、空の配列を返します。 [] => {位置:[]、ピーク:[]}
  • 値が前の値以下の場合、その値は自動的に破棄されます (プラトーは別のルールで処理されます)。 (配列[i]
  • 値が前のルールで破棄されず、かつ次の値より大きい場合、それは最大値です。 (配列[i] > 配列[i 1]) ?最大
  • 値が前述のルールによって破棄されず、かつ次の値と等しい場合、特別な処理が必要です。これは後で解決します。

2 番目に、特定の戻り値が必要です: {pos:[],peaks:[]}
この課題では、最大値の位置と値を求めます。

3 番目に、配列のループを設定する必要があります。
for (let i = 1 ; i 定義によれば、最初と最後の値は決して最大値にはならないため、最初と最後の値をスキップします。

4 番目に、ルールを実装します。

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      // TO DO
    }
  }
ログイン後にコピー
ログイン後にコピー

最後の部分を改良する必要があります。それが、ルールを定める際の上記の特別扱いです。これはサブプロセスとして機能する単なる別のループです:

    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

すべてを合計すると次のようになります:

function pickPeaks(arr){
  let cache = {pos:[], peaks:[]};
  if (arr == false) {
    return cache;
  }

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
  }

  return cache;
}
ログイン後にコピー
ログイン後にコピー

それではテストしてみましょう...やったー!合格しました!送信してみましょう...

ああ、違う。何???

Codewars - Pick peaks

この特定のテスト: pickPeaks([1,2,5,4,3,2,3,6,4,1,2,3,3,4,5,3,2,1,2,3, 5,5,4,3])
これは次を返します: {pos:[2,7,14,20],peaks:[5,6,5,5]}
返される内容: {pos:[2,7,14,20,20]、peaks:[5,6,5,5,5]}

でも、なぜでしょうか?ロジックは健全です。そして、すべてのループは正しく行われています...うーん...ちょっと待ってください...複製されます。位置 20、値 5。2 回あります。ここで何かが間違っています:

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      // TO DO
    }
  }
ログイン後にコピー
ログイン後にコピー

Dev Tools でデバッグを行った後、それを見つけました。問題は次のとおりです:

    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

break ステートメントがありません。 [...3,5,5,4,3] は、この終了条件が発生するシーケンスが見つかった場合にのみ内部ループから抜け出すため、2 番目の値を複製します:

function pickPeaks(arr){
  let cache = {pos:[], peaks:[]};
  if (arr == false) {
    return cache;
  }

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
  }

  return cache;
}
ログイン後にコピー
ログイン後にコピー

それ以外の場合は、そのまま続行されます。最大値が見つかった場合も終了する必要があることがわかります:

    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

修正済み:

        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
ログイン後にコピー

非効率的ですが効果的です。

気をつけてね。水を飲みましょう???

以上がCodewars - ピークを選択するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート