ホームページ >ウェブフロントエンド >jsチュートリアル >Codewars - ピークを選択する
ご挨拶
このシリーズでは、Codewars の課題と私の思考プロセスを投稿しています。私は可能な限り JS と Node 18 を使用しています。明確にするために、私はそれらを公正に使用しています。
お休みしていましたが、今は戻ってきました。ただし、解決策をここに投稿せずにいくつかの課題を実行しました。簡単なチャレンジに挑戦してみましょう。
ピークを摘むのは楽しいものです。数学的定義に従って極大値を見つける必要があります。 GFG より:
数学的には、f (a) ≥ f (a -h) および f (a) ≥ f (a h) ここで、h > 0 の場合、a は極大点と呼ばれます。
本質的には、どの値が最も近い値よりも大きいかを確認する必要があります。近傍が欠落している場合、それが極大値であるかどうかを検証できません。 したがって、配列の境界線はチェックしません。
次のソリューションは最適化されていません。それは 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; }
それではテストしてみましょう...やったー!合格しました!送信してみましょう...
ああ、違う。何???
この特定のテスト: 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 サイトの他の関連記事を参照してください。