我正在努力寻找满足以下代码挑战的解决方案,以满足所有要求并需要一些帮助:
var ex1 = [5, 5, 2, 1, *4*, 2, *6*, 2, 1, 2, 7, 7]; // {pos:[4,6], peaks:[4,6] } var ex2 = [3, 2, 3, *6*, 4, 1, 2, *3*, 2, 1, 2, 3]; // {pos:[3,7], peaks:[6,3]} var plateau = [1, *2*, 2, 2, 1]; // {pos:[1],peaks[2]}
- Find the local maxima or "peaks" of a given array but ignore local maxima at the beginning and end of the array.
- If there is a "plateau", return the position and value at the beginning of the "plateau."
- Any plateaus at beginning and end of the array should be ignored.
我提出的解决方案使用reduce函数来查看数组中当前元素之前和之后的元素。如果这些值小于当前元素的值,则当前元素是峰值。数组边缘的“峰值”将被忽略,因为它们不满足第一个或第二个标准。
function pickPeaks(array) {
return array.reduce((res, curr, i, arr) => {
if(arr[i-1] < curr && curr > arr[i+1]) {
res["pos"] = res["pos"] ? res["pos"].concat([i]) : [i];
res["peaks"] = res["peaks"] ? res["peaks"].concat([curr]) : [curr];
}
return res;
},{});
}
但是,该解决方案未能找到稳定点。
如果我将“右侧”条件逻辑更改为 curr >= arr[i+1]
它会找到稳定状态,但不会忽略“边缘”稳定状态,如下所示:
var plateau = [1, *2*, 2, 2, 1];
correct // {pos:[1],peaks[2]}
var ex1 = [5, 5, 2, 1, *4*, 2, *6*, 2, 1, 2, *7*, 7];
incorrect // {pos:[4,6,7], peaks:[4,6,10]}
我在这里缺少什么?如何检查“高原”是否位于数组的边缘?
最佳答案
您可以添加一个 while
循环来结束平稳期。
function getLocalMaxima(array) {
return array.reduce(function (r, v, i, a) {
var j = i;
while (v === a[++j]);
if (a[i - 1] < v && (a[i + 1] < v || a[i + 1] === v && a[j] < v)) {
r.pos.push(i);
r.peaks.push(v);
}
return r;
}, { pos: [], peaks: []});
}
var ex1 = [5, 5, 2, 1, 4, 2, 6, 2, 1, 2, 7, 7], // { pos: [4, 6], peaks:[4, 6] }
ex2 = [3, 2, 3, 6, 4, 1, 2, 3, 2, 1, 2, 3], // { pos: [3, 7], peaks: [6, 3]}
plateau = [1, 2, 2, 2, 1]; // { pos: [1], peaks[2] }
console.log(getLocalMaxima(ex1));
console.log(getLocalMaxima(ex2));
console.log(getLocalMaxima(plateau));
.as-console-wrapper { max-height: 100% !important; top: 0; }
关于javascript - 在有条件的数组中查找局部最大值 [JS],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48305975/