我已经编写了一个javascript函数来分析数组中最大的下降。但是仍然存在一个小问题。作为最大值,我总是从孔阵列而不是从液滴获得最大值。
示例: 数组:[100,90,80,120]
最大降幅将在100到80之间。因此max必须为100,min必须为80。我的函数始终返回整个数组中的最大值。就我而言120
function checkData(data) {
let max = 0
let min = 0
let drop = 0
for (let i = 0; i < data.length; i++) {
if (max < data[i]) {
max = data[i] //?
} else {
let tempDrop = max - data[i]
drop = Math.max(tempDrop, drop)
min = max - drop
}
}
return [max, min, drop]
}
答案 0 :(得分:6)
您的循环应跟踪当前的跌幅并将其与前一个最大的跌幅进行比较。您可以通过跟踪索引来做到这一点:
function checkData(data) {
let bestDropStart = 0
let bestDropEnd = 0
let bestDrop = 0
let currentDropStart = 0
let currentDropEnd = 0
let currentDrop = 0
for (let i = 1; i < data.length; i++) {
if (data[i] < data[i - 1]) {
// we are dropping
currentDropEnd = i
currentDrop = data[currentDropStart] - data[i]
} else {
// the current drop ended; check if it's better
if (currentDrop > bestDrop) {
bestDrop = currentDrop
bestDropStart = currentDropStart
bestDropEnd = currentDropEnd
}
// start a new drop
currentDropStart = currentDropEnd = i
currentDrop = 0
}
}
// check for a best drop at end of data
if (currentDrop > bestDrop) {
bestDrop = currentDrop
bestDropStart = currentDropStart
bestDropEnd = currentDropEnd
}
// return the best drop data
return [data[bestDropStart], data[bestDropEnd], bestDrop]
}
console.log(checkData([100, 90, 80, 120]))
console.log(checkData([100, 90, 80, 120, 30]))
console.log(checkData([70, 100, 90, 80]))
console.log(checkData([100, 90, 80, 120, 30, 50]))
您也可以通过仅保留当前和最佳放置的开始和结束值来做到这一点,但我的首选是明确地跟踪索引。这样对我来说似乎更清晰(更易于调试和维护)。
答案 1 :(得分:2)
您需要迭代一次数组(O(n)
),并保持最小和最大值的连续计数,以及:
function checkData(array) {
var currentmax = array[0];
var currentmin = array[0];
var overallmax = array[0];
var overallmin = array[0];
var i;
for (i = 1; i < array.length; i++) {
if (array[i] <= array[i - 1]) {
// value is same or decreased
currentmin = array[i];
} else {
// check if previous iteration was the largest
if (currentmax - currentmin > overallmax - overallmin) {
overallmax = currentmax;
overallmin = currentmin;
}
// restart
currentmax = array[i];
currentmin = array[i];
}
}
// check if last iteration was the largest
if (currentmax - currentmin > overallmax - overallmin) {
overallmax = currentmax;
overallmin = currentmin;
}
return [overallmax, overallmin, overallmax - overallmin];
}
console.log(checkData([100, 90, 80, 120]));
console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));
答案 2 :(得分:2)
听起来您希望返回的最大和最小与用于计算最大下降的相同,而不是总的最大和最小。在这种情况下,只需添加一个附加变量来存储drop更新时的变量。替换
drop = Math.max(tempDrop, drop)
带有if语句(伪代码):
if current_drop is greater than stored_drop:
stored_drop = current_drop
stored_max_min = current max and min
然后返回额外存储的最大值和最小值。
答案 3 :(得分:0)
您需要跟踪两件事:
i
的最大值。i
到列表末尾的最小值。然后,您只需要找到每个索引的跌幅并选择最大的一个。
代码如下:
function maxDrop (data) {
if (!data || data.length === 0) {
return;
}
const max = [];
const min = [];
for (let i = 0; i < data.length; i++) {
const left = data.slice(0, i);
const right = data.slice(i, data.length);
max.push(Math.max.apply(null, left));
min.push(Math.min.apply(null, right));
}
let maxDrop = max[0] - min[0];
let maxValue = max[0];
let minValue = min[0];
for (let j = 0; j < data.length; j++) {
const drop = max[j] - min[j];
if (maxDrop < drop) {
maxDrop = drop;
maxValue = max[j];
minValue = min[j];
}
}
return [maxValue, minValue, maxDrop];
}
console.log(maxDrop([100,90,80,120]))
console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
console.log(maxDrop([100,90,80,120,30]))
答案 4 :(得分:0)
要再添加一个。 一种可能的方法是先创建所有放置-放置范围,而不是放置最大放置的范围
带有reduce的版本:
function checkData(data) {
let dropInd = 1,
mx = data.reduce((arr,val, ind) => {
if(ind && val > data[ind-1])dropInd++;
arr[dropInd] = arr[dropInd] || {max:val};
arr[dropInd].min = val;
arr[dropInd].drop = arr[dropInd].max - val;
return arr;
}, []) //after reduce, islands are created based on 'dropInd'
.sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
[0]; //the first value now contains the maximum drop
return [mx.max,mx.min,mx.drop];
}
console.log(checkData([100, 90, 80, 120]));
console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));
答案 5 :(得分:-1)
这完全按照预期的方式工作(根据您的预期输出),如下面的代码片段所示。
问题必须出在如何将数据作为数组发送。
alert(checkData([100, 90, 80, 120]));
function checkData(data) {
let max = 0
let min = 0
let drop = 0
for (let i = 0; i < data.length; i++) {
if (max < data[i]) {
max = data[i] //?
} else {
let tempDrop = max - data[i]
drop = Math.max(tempDrop)
min = max - drop
}
}
return [max, min, drop]
}
// Output : 120, 80, 20
但是,如果您要查找的是“最大值”,“最小值”,然后是最大的差异,即最大值和最小值之间的差异(在给定的示例中为40),那么您可以简单地做到这一点。
>
alert(checkData([100, 90, 80, 120]));
function checkData(data) {
let max = data.reduce(function(a, b) {
return Math.max(a, b);
});
let min = data.reduce(function(a, b) {
return Math.min(a, b);
});
let drop = max-min;
return [max, min, drop];
}
// Output : 120, 80, 40
我之所以仅提及这一点,是因为我不知道为什么您说您期望最大的差异是20(在100和80的情况下),而您在同一阵列中有120和80,这意味着最大的差异是40。