Как я могу подсчитать, сколько горизонтальных мазков требуется, чтобы нарисовать массив зданий?

Учитывая массив целых чисел, каждый элемент представляет собой здание. Например: int buildings[] = {1, 4, 3, 2, 3, 1}.

Если бы я нарисовал здания горизонтально кистью, сколько ударов кистью я бы использовал?

Я должен написать функцию, которая возвращает количество этих мазков кистью. Например 5.

Как я могу подсчитать, сколько горизонтальных мазков требуется, чтобы нарисовать массив зданий?

Я могу легко сделать это во время выполнения O(n^2), используя 2 цикла.

  • Внешний контур проходит по уровням каждого здания (по самому высокому зданию).

  • Внутренний цикл работает с массивом от 0 до n и сравнивает разницу высот (0 или 1) между двумя соседними элементами.

Как я могу сделать это в O(n) времени и O(n) пространстве?

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
28
0
4 604
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Мазок кисти начинается всякий раз, когда высота увеличивается слева направо, и заканчивается, когда она уменьшается. Вам нужно только смотреть, когда он увеличивается, потому что, если вы просто посчитаете начальные точки каждого штриха, у вас будет счет хода. Вместо того, чтобы перебирать уровни высоты во внутреннем цикле, просто вычтите один уровень высоты из предыдущего, чтобы получить разницу.

В псевдокоде:

int BrushCount(int[] buildings)
{
    int brushCount = 0;
    int prevHeight = 0;
    for(int i = 0; i < buildings.length; i++)
    {
        if (buildings[i] > prevHeight)
             brushCount = brushCount + (buildings[i] - prevHeight);
        prevHeight = buildings[i];
    }
    return brushCount;
}

Работает за O(n).

Просто небольшая придирка - ваш псевдокод не подходит для двух примеров OP. Можете ли вы сказать, почему?

גלעד ברקן 30.05.2019 16:14

Обновление prevHeight должно происходить безоговорочно, иначе алгоритм будет некорректным, когда вам потребуется несколько мазков кисти на одной высоте.

AlexR 30.05.2019 18:59

При подсчете с конца массива в качестве начального значения результата используется последний элемент, а предыдущий элемент сравнивается с текущим.

Если они равны, то результат увеличивается на единицу; если предыдущий меньше текущего, ничего не делать; если предыдущий больше текущего, тогда результат = результат + предыдущий-текущий

int i=sizeof buildings;
int t=buildings[i]; 
while(i>0){
  if (buildings[i-1]-buildings[i]>0) t+=(buildings[i-1]-buildings[i]);
  else if (buildings[i-1]-buildings[i]==0) ++t;
  --i;
}
return t;

Немного кода гольфа :) (На основе отличного объяснение самгака.)

const f = A => A.reduce((a,b,i,A) => a + Math.max(0, b - A[i-1]));

console.info(f([1, 4, 3, 2, 3, 1]))
console.info(f([4, 1, 2, 1, 2, 2]))

@ Нил, что делает мою не «настоящей»?

גלעד ברקן 30.05.2019 23:28

Код-гольф заключается в том, чтобы сделать код максимально коротким. Это забавная игра, но ее никогда не следует использовать в коде, написанном для вашего работодателя.

David Hammen 31.05.2019 01:12

@ Нил, это только в том случае, если ты планируешь выиграть раунд. Поддерживаю свою строчку является кода гольфа, пусть и не самую короткую.

גלעד ברקן 31.05.2019 02:56
public static int brushCount(int[] buildings)
{
    int count=0;
    for(int i=0; i<=buildings.length-1; i++){
        if ((i+1)<(buildings.length)){
            if (buildings[i]>buildings[i+1]){
                count += buildings[i]-buildings[i+1];
            }
        }else{
            count += buildings[i];
        } 
    }
    return count;
}

Другие вопросы по теме