問候。
我在這個系列中發布了 Codewars 挑戰和我的思考過程。我盡可能使用 JS 和 Node 18。只是為了清楚起見,我正在合理地使用它們。
我休息了,現在我回來了。不過,我還是做了一些挑戰,但沒有在這裡發布解決方案。讓我們來迎接一個簡單的挑戰。
挑選山峰是一件有趣的事。您需要根據其數學定義找到局部最大值。來自 GFG:
數學上,f (a) ≥ f (a -h) 且 f (a) ≥ f (a h),其中 h > 0,則a稱為局部極大點。
本質上,我們需要看看哪些值比它最接近的鄰居大。如果鄰居遺失,我們無法驗證它是否是局部最大值。 所以我們不會檢查陣列的邊界。
以下解決方案尚未最佳化。應該是一關。此外,我被教導要避免使用break和continue。但它確實起到了作用。
首先我們設定規則:
其次,它需要一個特定的回傳值:{pos:[], Peaks:[]}
此挑戰要求最大值的位置和值。
第三,我們需要為陣列設定一個循環:
for (令 i = 1 ; i
我們跳過第一個和最後一個值,因為根據定義它們永遠不會是最大值。
四、我們執行規則:
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。出現了兩次。這裡出了點問題:
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]); } } }
它缺少一個break語句。 [...3,5,5,4,3] 重複第二個值,因為它只有在找到出現此退出條件的序列時才會跳出內部循環:
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中文網其他相關文章!