Отлаживайте проблему с фруктами в корзинах в Javascript с помощью объекта карты

#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;
}
};