#javascript #arrays #for-loop
#javascript #массивы #for-цикл
Вопрос:
Моя идея состоит в том, чтобы перебирать массив и каждый раз суммировать все элементы в массиве, кроме одного элемента, затем находить наименьшую сумму и наибольшую сумму.
Я знаю, что .splice()
это может удалить любой элемент из массива. Но в настоящее время с моим кодом он удаляет только один элемент из массива один раз. Т.Е. Это дает мне только один фрагмент:
function miniMaxSum(arr) {
let smallestSum = 0;
let largestSum = 0;
for (let i = 0; i < arr.length; i ) {
let chunk = arr.splice(1);
console.log(chunk);
if (chunk > largestSum) largestSum = chunk;
if (chunk < smallestSum) smallestSum = chunk;
}
return (smallestSum, largestSum);
}
Мне нужно каждый раз удалять один элемент из массива во время цикла, а затем получать максимальную и минимальную суммы из этого массива.
Итак, для данного массива [1, 2, 3, 4, 5]
Я должен получить следующие возможные «куски»:
[2, 3, 4, 5]
, [1, 3, 4, 5]
, [1, 2, 4, 5]
, [1, 2, 3, 5]
, [1, 2, 3, 4]
.
Фрагмент с наибольшей суммой равен [2, 3, 4, 5]
И фрагмент с наименьшей суммой равен [1, 2, 3, 4]
.
Как я могу настроить свой код, чтобы получить все возможные 4-значные массивы в пределах данного массива, чтобы я мог сравнивать их суммы, все еще используя цикл for? Или, если не с помощью цикла for, что бы вы еще предложили?
РЕДАКТИРОВАТЬ: теперь используйте Math.min()
и Math.max()
, чтобы получить наименьшие и наибольшие элементы в массиве. Затем используется .filter()
для удаления этих элементов для создания новых массивов. Затем получаем суммы этих массивов.
function miniMaxSum(arr) {
let smallest = Math.min(...arr);
let largest = Math.max(...arr);
let smallestArray = arr.filter(element => element !== largest);
let largestArray = arr.filter(element => element !== smallest);
let sumOfSmallestArray = 0;
let sumOfLargestArray = 0;
for (let i = 0; i < smallestArray.length; i ) {
sumOfSmallestArray = smallestArray[i];
}
for (let i = 0; i < largestArray.length; i ) {
sumOfLargestArray = largestArray[i];
}
return ([sumOfSmallestArray, sumOfLargestArray]).toString();
}
Но даже если это работает в моей консоли, это не работает в HackerRank.
Комментарии:
1. Наблюдение: блок с наибольшей суммой — это блок без наименьшего элемента, а блок с наименьшей суммой — это блок без наибольшего элемента. Похоже, что эта проблема на самом деле просто другая форма «найти самые большие и самые маленькие элементы массива».
2. Как было предложено @p.s.w.g в аналогичных строках. Сначала отсортируйте свой массив, затем просто удалите первый элемент и добавьте для максимальной суммы и для минимального выноса последнее число. Цикл не требуется.
Ответ №1:
Ключ в том, чтобы сначала отсортировать этот массив, тогда минимум будет первым элементом, а максимум — последним, следовательно, если вы хотите получить минимальный набор, это будет массив без наибольшего значения (последнего элемента), и если вы хотите получить максимальный набор, это будетмассив без наименьшего значения (первого элемента).
let data = [1, 3, 2, 4, 5];
// sort first
data = data.sort();
// to get the sets only
let maxSet = data.slice(1);
let minSet = data.slice(0, -1);
console.log(minSet, maxSet);
// to get just the max/min value
const sum = data.reduce((a, total) => a total, 0);
console.log(sum - data[data.length - 1], sum - data[0]);
Комментарии:
1. Использование
.sort()
— действительно хорошая идея — спасибо. Это работает в HackerRank, когдаconsole.log(minSet, maxSet);
закомментировано.2. Рад, что смог помочь.
3. Одна вещь, которую я замечаю, это то
.sort()
, что она не работает для массивов, которые передаются в функцию: codepen.io/AnonymousName/pen/LvQwJv?editors=1112 . Похоже, вам нужно либо объявить свой массив внутри функции (как вы сделали в своем ответе), либо использовать функцию обратного вызова: codepen.io/HappyHands31/pen/axqeKR?editors=11124. Это не проблема. Сортировка по умолчанию выполняет сортировку на основе строк, поэтому вы получаете неправильные сортировки для целых чисел.
Ответ №2:
Задача HackerRank просто запрашивает суммы, поэтому вы можете сделать один проход по массиву, чтобы вычислить 3 факта:
- Максимальный элемент (
a
) - Минимальный элемент (
b
) - Общая сумма всех элементов (
c
)
Сумма наименьшего фрагмента будет c - a
равна, а сумма наибольшего будет равна c - b
.
Вот однострочное решение, использующее reduce
:
var arr = [1, 2, 3, 4, 5];
var [a, b, c] = arr.reduce(([a, b, c], x) => [a > x ? a : x, b < x ? b : x, c x], [NaN, NaN, 0]);
console.log(c - a, c - b);
Примечание: NaN
‘s здесь только для того, чтобы заставить начальные условия ( a > x
/ b < x
быть ложными)
Комментарии:
1. Учитывая ваш оригинальный комментарий и логику, не могу ли я найти наименьший элемент в массиве с использованием
Math.min()
и самый высокий элемент в массиве с использованиемMath.max()
? Тогда как я могу вычестьlowest
иhighest
из массива, чтобы получитьsmallestArray
иlargestArray
? (см. Мое редактирование).2. @HappyHands31 Да, это именно то, на что я намекал в исходном комментарии. Вот как работает ответ Нины Шольц, и это отличное решение. Однако, прочитав задачу HackerRank, я понял, что вам не обязательно выяснять, что это за фрагмент, только какова сумма. На самом деле вам не нужно вычислять эти промежуточные массивы, если вместо этого вы просто обрабатываете суммы. Мой ответ технически не отвечает на исходный вопрос, я просто предлагаю альтернативный подход к решению проблемы.
3. @HappyHands31 рассмотрите ввод
[1, 1, 3, 5, 5]
, ваш фильтр исключает два 1 и два 5, таким образом, сбой.
Ответ №3:
Вы можете получить минимальные и максимальные значения массива и отфильтровать массив, не принимая минимальное или максимальное значение один раз.
var data = [1, 2, 3, 4, 5],
min = Math.min(...data),
max = Math.max(...data),
dataMin = data.filter(v => v !== min || !(min = -Infinity)),
dataMax = data.filter(v => v !== max || !(max = Infinity));
console.log(...dataMin);
console.log(...dataMax);
Более классический подход
function minMax(array) {
var min = array[0],
max = array[0],
sum = array[0],
i, v;
for (i = 1; i < array.length; i ) {
v = array[i];
sum = v;
if (v > max) max = v;
if (v < min) min = v;
}
console.log(sum - min, sum - max);
}
minMax([1, 2, 3, 4, 5]);
Комментарии:
1. Я думаю, что это решение имеет наибольший смысл, но я не понимаю
.filter(v => v !== min || !(min = -Infinity)),
. Можете ли вы объяснить это, пожалуйста? Возможно, обозначение стрелки сбивает меня с толку. Вот скрипка JS, пытающаяся следовать вашей логике: jsfiddle.net/hyp6m1eu2. Просто нужно научиться вычитать
min
изdata
, чтобы найтиlargestArray
, и вычитатьmax
изdata
, чтобы найтиsmallestArray
.3. назначение состоит в том, чтобы предотвратить исключение значения более одного раза, если у вас есть значение более одного раза. присвоенное значение является либо возможным минимальным, либо максимальным значением.
4. Не могли бы вы взглянуть на правку, которую я внес в свой исходный пост, пожалуйста? Поскольку я могу получить элементы
smallest
andlargest
из массива, используяMath.min()
andMath.max()
, как я могу затем вычесть эти элементы из массива для создания двух новых массивов?smallestArray
иlargestArray
? Тогда я могу вернуть сумму элементов этих двух новых массивов.5. Это работает в моей консоли, как и мой отредактированный код выше, но ни один из них не работает в HackerRank по какой-либо причине.
Ответ №4:
Вы можете sort
массив и для min
взять первые четыре и добавить их, а для max
взять последние четыре и добавить их
let arr = [1, 2, 3, 4, 5]
let minAndMax = (arr) => {
arr = arr.sort((a,b) => a - b)
let op = {}
op.minArr = arr.slice(0,4)
op.min = op.minArr.reduce((a,b) => a b, 0)
op.maxArr = arr.slice(arr.length-4,)
op.max = op.maxArr.reduce((a,b) => a b ,0)
return op
}
console.log(minAndMax(arr))
Ответ №5:
Это решение обходит индексы среза, вычисляет сумму и, когда найдено максимальное значение, оно вводится в результат. Наконец, результат анализируется:
var arr = [4, 8, 2, 6, 12];
var ln = arr.length;
var maxSum = undefined;
var result = "";
for (var splIndex = 0; splIndex < ln; splIndex ) {
var item = arr.splice(splIndex, 1);
var sum = 0;
for (var it of arr) sum = it;
if ((maxSum === undefined) || (maxSum < sum)) {
maxSum = sum;
result = JSON.stringify(arr);
}
arr.splice(splIndex, 0, item[0]);
}
console.log(JSON.parse(result));
Редактировать
Конечно, более простое решение — найти минимум и вычислить сумму без него.
Ответ №6:
Работает следующая функция:
function miniMaxSum(arr) {
var _arr = arr.sort((a, b) = > a - b)
var minVals = _arr.slice(0, 4)
var maxVals = _arr.slice(1)
const arrSum = __arr = > __arr.reduce((a, b) = > a b, 0)
var minSum = arrSum(minVals)
var maxSum = arrSum(maxVals)
console.log(minSum, maxSum)
}
Ответ №7:
let arr = [15 ,12, 33, 25, 4];
//sort array
const arrSort = arr.sort((a,b)=> a-b );
console.log(arrSort);
//get values and sum
var max = arrSort.filter(value => value < Math.max(...arrSort)).reduce((ac,at)=>{
ac = at;
return ac;
},0);
var min = arrSort.filter(value => value > Math.min(...arrSort)).reduce((ac,at)=>{
ac = at;
return ac;
},0);
console.log(max);
console.log(min);
Ответ №8:
Это сработало для меня.
let minValue, maxValue
const ascendingArray = arr.sort((a,b) => a - b)
const smallestNumber = ascendingArray[0]
const biggestNumber = ascendingArray[ascendingArray.length -1]
if(smallestNumber !== biggestNumber){
const biggestArray = arr.filter((number) => {
return number !== smallestNumber
})
const smallestArray = arr.filter((number) => {
return number !== biggestNumber
})
minValue = smallestArray.reduce((a,b) => a b, 0)
maxValue = biggestArray.reduce((a,b) => a b, 0)
console.log(minValue, maxValue);
}
else{
const arraySliced = arr.slice(0, 4)
const value = arraySliced.reduce((a,b) => a b, 0)
console.log(value, value);
}
Ответ №9:
function miniMaxSum(arr) {
var soma = 0
let t = 0
for (var i = 0; i < arr.length; i ) {
soma = arr[i]
max = soma - arr[i]
}
let min = soma - arr[0]
return max ' ' min
}
console.log(miniMaxSum([7, 69, 2, 221, 8974]))
Ответ №10:
Вот более чистый подход к решению этой проблемы.
function miniMaxSum(arr) {
let min, max, sum, arrMin, arrMax; // declare variables
min = Math.min(...arr) // gets the smallest value from the arr
max = Math.max(...arr) // gets the largest number from the arr
sum = arr.reduce((a,b) => a b, 0); // reduce used to add all values in arr
arrMin = sum - max; // excludes the largest value
arrMax = sum - min; // excludes the smallest value
console.log(arrMin ' ' arrMax) // output
}
Ответ №11:
простое решение
const miniMax = arr => {
let min = arr[0];
let max = arr[0];
for(let i = 0; i < arr.length; i ) {
if(arr[i] <= min) {
min = arr[i];
}
if (arr[i] >= max) {
max = arr[i];
}
}
let sum = arr.reduce((acc,curr) => acc curr);
console.log(sum - max, sum - min);
}
miniMax([5,5,5,5,5]);
// result : 20 20
miniMax([1,2,3,4,5]);
// result : 10 14
Ответ №12:
Я получаю ответ очень простым способом
function miniMaxSum(arr) {
let minval=arr[0];
let maxval=0;
let totalSum=0;
for(let i=0;i<arr.length;i ){
if (arr[i]>maxval){
maxval=arr[i];
}
if (arr[i]<minval){
minval=arr[i];
}
totalSum=totalSum arr[i];
}
let minsum=totalSum - maxval;
let maxsum=totalSum - minval;
console.log( minsum,maxsum);
}
Ответ №13:
Используйте Math
методы сборки, чтобы найти max и min:
function miniMaxSum(arr) {
const min = Math.min(...arr);
const max = Math.max(...arr);
const sum = arr.reduce((a, b) => a b);
console.log(sum - max, sum - min);
}