#javascript #object #debugging #hashmap
Вопрос:
Я застрял в проблеме с кодированием ниже. Похоже, что в Map.prototype.entries () есть ошибка, однако я хотел бы получить ваши экспертные комментарии по этому поводу
Значение вопроса: Какова длина самого длинного подмассива, содержащего до двух различных целых чисел?
Вот постановка проблемы , это проблема LC
Вы посещаете ферму, на которой есть один ряд фруктовых деревьев, расположенных слева направо. Деревья представлены целочисленным массивом фруктов, где фрукты[i] — это тип фруктов, которые производит i-е дерево.
Вы хотите собрать как можно больше фруктов. Однако у владельца есть некоторые строгие правила, которым вы должны следовать:
У вас есть только две корзины, и в каждой корзине может содержаться только один вид фруктов. Нет никаких ограничений на количество фруктов, которые может вместить каждая корзина. Начиная с любого дерева по вашему выбору, вы должны выбрать ровно один плод с каждого дерева (включая начальное дерево), двигаясь вправо. Собранные фрукты должны поместиться в одной из ваших корзин. Как только вы достигнете дерева с фруктами, которые не помещаются в ваши корзины, вы должны остановиться. Учитывая целочисленный массив фруктов, верните максимальное количество фруктов, которые вы можете выбрать.
Ниже приведен мой код
var totalFruit = function(fruits) {
// create a map of fruit type
var fruitTypes = new Map();
var fruitCount = 0;
var maxFruits = 0;
// iterate till end
for(var indx=0; indx<fruits.length; indx )
{
console.log('nI am at index:' indx ' now and value is:' fruits[indx]);
// add only 2 types of fruit
if(fruitTypes.size <=2)
{
fruitTypes.set(fruits[indx], fruitCount);
maxFruits = fruitCount;
console.log('n maxFruit count is ' maxFruits);
}
// if the type of fruit is more than two
if(fruitTypes.size > 2)
{
const iterator1 = fruitTypes.entries();
console.log(iterator1.next().value);
// expected output: ["0", "foo"]
// now remove the first set of fruit
console.log('nfruittype size is: ' fruitTypes.size ' and fruit count is: ' fruitCount);
const key = fruitTypes.keys();
var keyToDelete = key.next().value;
const value = fruitTypes.values();
var valueToSubtract = value.next().value;
console.log('Deleting fruit type: ' keyToDelete ' and substracting number of fruits=' valueToSubtract);
fruitTypes.delete(keyToDelete);
fruitCount = fruitCount - valueToSubtract;
console.log('nfruittype size now is: ' fruitTypes.size ' and fruit count is: ' fruitCount);
}
}
console.log("nmaxFruits=" maxFruits ", fruitcount=" fruitCount);
return Math.max(maxFruits, fruitCount);
};
var fruits = [3,3,3,1,2,1,1,2,3,3,4];
console.log('nmaximum fruit count=' totalFruit(fruits));
Код работает нормально, но не работает для данного тестового случая, т. е.
Вход: [3,3,3,1,2,1,1,2,3,3,4] Выход: 4 Ожидается: 5
Может ли кто-нибудь помочь в устранении неполадок, в которых я допустил ошибку?
Комментарии:
1. Я не понимаю, почему вы ожидаете 5. Вы выбираете 3,3,3 в первой корзине. Затем он переключается на фрукты 1, поэтому вы выбираете 1 во 2-й корзине, затем он переключается на фрукты 2, и вы больше не можете собирать фрукты. Таким образом, всего должно быть 4.
2. Ах… на самом деле, я думаю, что понимаю. Вы можете начать с любого дерева для КАЖДОЙ корзины
3. Вопрос означает: какова длина самого длинного подмассива, содержащего до двух различных целых чисел?
4. На самом деле это означает, каковы 2 самых длинных подмассива с одинаковыми целыми числами
Ответ №1:
Это не все причудливо написано в 1 строке кода или что-то в этом роде, но работает хорошо. Вы можете указать дополнительные корзины:
var totalFruit = function(fruits) {
// create a map of fruit type
const nBASKETS = 2;
let nTotalFruit = 0;
let cur_fruit = 0;
let nCurLongest = 0;
let nCurFruitCnt = 0;
let nBeginIdx = 0;
for(let i = 0; i < nBASKETS; i )
// find longest sub-array, record its size, then remove it
for(var indx=0; indx<fruits.length; indx ){
if(indx)
if(fruits[indx] == cur_fruit)
nCurFruitCnt
else {
if(nCurFruitCnt > nCurLongest){
nCurLongest = nCurFruitCnt;
nBeginIdx = indx - nCurFruitCnt
}
nCurFruitCnt = 1;
cur_fruit = fruits[indx]
}
else{ // left boundary
cur_fruit = fruits[indx];
nCurFruitCnt = 1;
nCurLongest = 1;
nBeginIdx = 0
}
if(indx == fruits.length - 1){ // right boundary
if(nCurFruitCnt > nCurLongest){
nCurLongest = nCurFruitCnt;
nBeginIdx = indx - nCurFruitCnt
}
// processed array... remove longest sub-array
nTotalFruit = nCurLongest;
fruits.splice(nBeginIdx, nCurLongest)
}
}
return nTotalFruit
}
var fruits = [3,3,3,3,3,1,1,2,1,1,3,3,3,3];
console.log('nmaximum fruit count = ' totalFruit(fruits));
Ответ №2:
- Вам нужно отслеживать
maxFruits
время выполнения итерации — не перезаписывайте ее безоговорочноmaxFruits = fruitCount
, вместо этого звонитеmaxFruits = Math.max(fruitCount, maxFruits);
. В противном случае, возможно, более высокая предыдущая запись может быть потеряна. - С
fruitTypes.set(fruits[indx], fruitCount);
помощью вы не добавляете правильное значение — вы должны добавлять к текущему значению по этому индексу на карте. Например, учитывая[1, 2, 2]
, что после третьей итерации вы хотели бы, чтобы карта содержала
1 => 1,
2 => 2
и не
1 => 1
2 => 3
потому что есть два элемента типа 2, а не три.
Но я не думаю, что этот подход является правильным, так как было бы немного некрасиво определять, сколько элементов нужно вычесть при встрече с новым временем. Например, с
[1, 2, 1, 1, 3]
при повторении 3 вам нужно будет определить, что вам нужно удалить как 1 (индекс 0), так и 2 (индекс 1) — суммируя до 2, оставляя остальные. Самый ранний ключ на карте также не обязательно нужно удалять, как вы можете видеть из приведенного выше примера.
Вот как я бы это сделал — отслеживал как количество отдельных последовательных типов до текущей итерации (например [3, 3, 3]
, — > размер 3), так и количество двух последовательных типов до текущей итерации (например, > [4, 3, 3, 3]
— > размер 4). Когда найден другой тип, назначьте одинарный последовательный для двух последовательных и возьмите максимум двух последовательных, найденных за все итерации.
const calculateFruits = (fruitTypes) => [...fruitTypes.values()].reduce((a, b) => a b);
var totalFruit = function(fruits) {
let consecutiveIdentical = 0;
let consecutiveOfTwoTypes = 0;
let currentType;
let currentTypes = [];
let maxFruitsSoFar = 0;
for (const type of fruits) {
if (!currentTypes.includes(type)) {
consecutiveOfTwoTypes = consecutiveIdentical;
if (currentTypes.length === 2) {
currentTypes = [currentType, type];
consecutiveOfTwoTypes = consecutiveIdentical;
} else {
currentTypes.push(type);
}
}
consecutiveOfTwoTypes ;
if (currentType !== type) {
consecutiveIdentical = 1;
} else {
consecutiveIdentical ;
}
currentType = type;
maxFruitsSoFar = Math.max(maxFruitsSoFar, consecutiveOfTwoTypes);
}
return maxFruitsSoFar;
}
var fruits = [33, 3, 3, 2, 1, 1, 2, 3, 3, 3, 3]
console.log('maximum fruit count=' totalFruit(fruits));
Комментарии:
1. Это не работает для данного ввода:
[3, 3, 3, 3, 2, 1, 1, 2, 3, 3, 3, 3] // = 8
Ответ №3:
Сначала я делаю копию видов фруктов,
Затем для разных фруктов я проверяю данные цепочки в строке
const calculate = (fruits) => {
const typeOfFruits = [...(new Set(fruits))];
let total = 0;
typeOfFruits.forEach(f => {
let NumberOfFruit = 0;
let chain = false;
for (let i = 0; i < fruits.length; i ) {
if (!(!!NumberOfFruit)) {
if (fruits[i] === f amp;amp; fruits[i 1] === f) {
NumberOfFruit = 1;
chain = true;
}
}
else {
if (chain) {
if (fruits[i] === f) NumberOfFruit = 1;
else chain = false;
}
}
}
total = NumberOfFruit;
});
return total;
}
calculate([3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4]); // 5
Комментарии:
1. Это не работает для этого ввода:
calculate([3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 3]); // 6
Ответ №4:
var totalFruit = function(fruits) {
if(fruits.length <=2)
{
console.log("no point going forward, since the length is " fruits.length);
return fruits.length;
} else {
// create a map of fruit type
var fruitTypes = new Map();
var maxFruits = 0;
var prevKey = 0;
var lastTwoConsequtiveValues = 0;
// iterate till end
for(var indx=0; indx<fruits.length; indx )
{
//console.log('nI am at index:' indx ' now and value is:' fruits[indx]);
// add only 2 types of fruit
if(fruitTypes.size <=2)
{
var keyFruit = fruits[indx];
fruitTypes.set(keyFruit, fruitTypes.get(keyFruit) == undefined ? 1 : fruitTypes.get(keyFruit) 1)
//if(fruitTypes.size >= 2){
console.log("n******************");
console.log([...fruitTypes.entries()]);
var values = fruitTypes.values();
var val1 = values.next().value;
if(val1 == undefined)
val1 = 0;
var val2 = values.next().value;
if(val2 == undefined)
val2 = 0;
// before deleting store the fruit value
console.log('nval1=' val1 ' val2=' val2);
lastTwoConsequtiveValues = val1 val2;
console.log('n 1. lastTwoConsequtiveValues =' lastTwoConsequtiveValues);
maxFruits = Math.max(maxFruits, lastTwoConsequtiveValues);
console.log('n 1. Maximum value is ' maxFruits);
console.log([...fruitTypes.entries()]);
console.log("n ");
//}
}
// if the type of fruit is more than two
if(fruitTypes.size > 2)
{
console.log('nfruittype size is: ' fruitTypes.size);
//if(fruitTypes.size >= 2){
var values = fruitTypes.values();
var val1 = values.next().value;
var val2 = values.next().value;
if(val1 == undefined)
val1 = 0;
if(val2 == undefined)
val2 = 0;
// before deleting store the fruit value
console.log('nval1=' val1 ' val2=' val2);
lastTwoConsequtiveValues = val1 val2;
console.log('n 2. lastTwoConsequtiveValues =' lastTwoConsequtiveValues);
maxFruits = Math.max(maxFruits, lastTwoConsequtiveValues);
console.log('n 2. Maximum value is ' maxFruits);
// }
// now delete the first key
var keys = fruitTypes.keys()
keyToDelete = keys.next().value;
console.log('nDeleting deleteFirstKey fruit type: ' keyToDelete);
fruitTypes.delete(keyToDelete);
console.log([...fruitTypes.entries()]);
}
}
console.log("nmaxFruits=" maxFruits);
return maxFruits;
}
};