在给定数组中查找最小值和最大值,其中约束应最小值索引应小于其最大值
Posted
技术标签:
【中文标题】在给定数组中查找最小值和最大值,其中约束应最小值索引应小于其最大值【英文标题】:Find Minimum and Maximum in given array where constraints should minimum value index should be less than its maximum 【发布时间】:2021-08-17 07:18:36 【问题描述】:给定数组 [“1510”、“1518”、“1520”、“1523”、“1530”、“1483”、“1485”] 预期输出:-
Smallest - 1510
Largest - 1530
另一个数组 ["310", "314", "320", "319", "323", "313", "330"] 预期输出:-
Smallest - 310
Largest - 330
我下面的代码获得了解决上面列出的第一个问题时遇到问题的最小值和最大值,因为它返回 1483 作为最小和 1485 作为最大。 max 和 min 之间的差异应该更大。
知道如何获得它吗?
function minMax(array)
if(array.length <= 0) return [0, 0];
let max = Math.max.apply(null, array);
let min = Math.min.apply(null, array);
let max_index = array.lastIndexOf(String(max));
let min_index = array.indexOf(String(min));
if(min_index >= max_index)
array.splice(max_index, 1);
[min, max] = minMax(array);
return [min, max];
【问题讨论】:
顺便说一句,为什么不是数组中的数字? 如果数组按照[3, 2, 1]
这样的降序排列怎么办?
有两个可能的答案:[绝对最小元素,它右边的最大值] 或 [绝对最大元素,它左边的最小值]。你在找哪一个?
@Akhil,数组不应该被排序。它只会是未排序的数组。
@NinaScholz,您可以将其作为数字数组。这只是我正在工作的东西,它具有数组元素作为字符串(这是一个数字)
【参考方案1】:
单次遍历数组:
-
从数组末尾迭代到开头。
跟踪最大值和最小值以及最小值/最大值对列表
检查每个项目
如果找到的项目超过当前最大值,
将当前最小值/最大值添加到对列表中
将当前项目设为最大值并重置最小值
否则,如果当前项小于当前最小值,则将其设为最小值。
否则什么都不做。
然后将最后一个最小值/最大值对添加到列表中。
此时,您有一个可能返回的最小/最大对的列表。您必须从头到尾检查它们,以找到第一个设置了最小值并返回它。或者返回一组默认的最小值/最大值。
function minMax(arr)
let max = -Infinity;
let min = Infinity;
const candidates = [];
for (let i = arr.length-1; i >= 0; i--)
const item = Number(arr[i]);
if (item > max)
candidates.push([min, max]);
max = item;
min = Infinity;
else if (item < min)
min = item;
candidates.push([min, max]);
// Instead of return fixed first or last element below code would return first element from last which is finite.
for(let i = candidates.length - 1; i >= 0; i--)
if(Number.isFinite(candidates[i][0])) return candidates[i];
return [0, 0];
console.log(minMax(["1510", "1518", "1520", "1523", "1530", "1483", "1485"]));
console.log(minMax(["310", "314", "320", "319", "323", "313", "330"]));
console.log(minMax(["350", "314", "320", "319", "323", "313", "330"]));
console.log(minMax(["7", "6", "1", "2"]));
console.log(minMax(["4", "3", "2", "1"]));
【讨论】:
这可行,但会出现这样的数组问题 ["350", "314", "320", "319", "323", "313", "330"]。这个数组应该返回 314 作为最小值和 330 作为最大值。 @KailashPrabhu 我明白了,我没有意识到是这种情况。在这种情况下,我必须考虑一下。 感谢这工作非常好,也可以理解。虽然尼娜的回答有效。由于代码复杂度比 Nina 的要低,因此将其标记为答案。[7,6,1,2] => [Infinity, 6]
@georg,在你的数组中它应该返回 1 作为最小值和 2 作为最大值。希望这应该消除混乱。哎呀!说得太早了。是的,看起来 VLAZ 代码为上述情况返回 Infinity。【参考方案2】:
你可以使用类似下面的东西
function minMax(array)
let max = Math.max.apply(null,array)
let newArray= array.slice(0,array.indexOf(+max)-1)
let min=Math.min.apply(null, newArray);
return [min, max];
【讨论】:
【参考方案3】:你可以
获取本地最小值和最大值数组, 如果两个值都存在,则将它们分组为最小值和最大值对, 如果在更大的索引上找到最大值,则更改最大值, 获取 delta 最大的一对。function minMax(numbers)
return numbers
.reduce((r, v, i, a) =>
if (!(r.length & 1) === a[i - 1] < v) r[r.length - 1] = v;
else r.push(v);
return r;
, [])
.reduce((r, v, i, a) =>
if (i & 1) r.push([a[i - 1], v]);
return r;
, [])
.reduce((r, [min, max], i, a) => (r || a).map(([left, right], j) => [
left,
i > j && max > right ? max : right
]), undefined)
.reduce((a, b) => a[1] - a[0] >= b[1] - b[0] ? a : b);
console.log(minMax([1510, 1518, 1520, 1523, 1530, 1483, 1485])); // 1510 1530
console.log(minMax([310, 314, 320, 319, 323, 313, 330])); // 310 330
console.log(minMax([9, 3, 4, 1])); // 3 4
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
完美!这确实返回了我正在搜索的预期值。但它看起来确实很复杂。有什么方法可以详细解释一下吗?更容易理解它是如何工作的。 @georg,看起来 Nina 的实现处理得很好。对于[7,6,1,2]
的情况,它返回期望值 min 为 1,max 为 2。【参考方案4】:
此问题与buy and sell stock 相同。您首先需要尽可能多地买入股票并卖出。因此,在每个索引处,您需要知道右侧最大的元素。
-
从末尾遍历数组,并在每个索引处存储到目前为止的最大元素。
For the list [1510, 1518, 1520, 1523, 1530, 1483, 1485] maxList will look like [1530, 1530, 1530, 1530, 1530, 1485, 1485] difference [20, 12, 10, 7, 0, 2, 0 ] so answer will be 1510 and 1530.
【讨论】:
以上是关于在给定数组中查找最小值和最大值,其中约束应最小值索引应小于其最大值的主要内容,如果未能解决你的问题,请参考以下文章
Javascript:使用 reduce() 查找最小值和最大值?