在具有条件的数组中查找局部最大值[JS]

时间:2018-01-17 16:39:26

标签: javascript arrays

我正在努力寻找满足所有要求的以下代码挑战的解决方案,并可以使用一些帮助:

     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]}
     
      
  1. 找到当地最大值或者#34;峰值"给定数组但忽略本地      数组开头和结尾的最大值。
  2.   
  3. 如果有"高原",请返回位置和值      高原的开始。"
  4.   
  5. 应忽略数组开头和结尾的任何平台。
  6.   

我提出的解决方案使用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;
  },{});
}

然而,这种解决方案未能找到高原。

如果我改变我的&#34;右边&#34;条件逻辑到curr >= arr[i+1]它找到了平台,但没有忽略&#34; edge&#34;高原如此:

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]}

我在这里缺少什么?如何检查&#34;高原&#34;是在数组的边缘还是没有?

2 个答案:

答案 0 :(得分:0)

我的解决方案是提前删除平台,并对更新峰值结果进行微调:

function trimEndingPlateaus(array){
 var end = array.length -1;
  for (var i = 1; i < array.length -1; i++){
    if (array[array.length - 1 - i] === array[end]) end--;
    else break;
  }

  return array.slice(0, end);
}

function pickPeaks(array) {
  return trimEndingPlateaus(array).reduce((res, curr, i, arr) => {
    // find peaks

    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;
  },{});
}

测试用例:

var plateau = [1, 2, 2, 2, 1];
var ex1 = [5, 5, 2, 1, 4, 2, 6, 2, 1, 2, 7, 7];    
var ex2 = [3, 2, 3, 6, 4, 1, 2, 3, 2, 1, 2, 3];

console.log(pickPeaks(plateau));
//Outputs: {"pos":[1],"peaks":[2]}

console.log(pickPeaks(ex1));
//Outputs: {"pos":[4,6],"peaks":[4,6]} 

console.log(pickPeaks(ex2));
//Outputs: {"pos":[3,7],"peaks":[6,3]}

答案 1 :(得分:0)

您可以添加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; }