web-dev-qa-db-fra.com

Comment puis-je compter le nombre de coups de pinceau horizontaux nécessaires pour dessiner un ensemble de bâtiments?

En fonction d'un tableau d'entiers, chaque élément représente un bâtiment. Par exemple: int buildings[] = {1, 4, 3, 2, 3, 1}.

Si je dessinais les bâtiments horizontalement avec un pinceau, combien de coups de pinceau utiliserais-je?

Je devrais écrire une fonction qui renvoie le nombre de ces coups de pinceau. Par exemple 5.

enter image description here

Je peux le faire facilement au moment de l'exécution O(n^2), en utilisant 2 boucles.

  • La boucle externe fonctionnant aux niveaux de chaque bâtiment (selon le bâtiment le plus haut).

  • La boucle interne s'exécute sur le tableau de 0 À n et compare la différence de hauteur (0 Ou 1) Entre deux éléments proches.

Comment faire cela dans l'espace O(n) time et O(n)?

24
Shir K

Un coup de pinceau commence chaque fois que la hauteur augmente de gauche à droite et se termine lorsqu'elle diminue. Il suffit de regarder quand il augmente, car si vous comptez simplement les points de départ de chaque coup, vous aurez le nombre de coups. Au lieu de boucler sur les niveaux de hauteur dans une boucle intérieure, il suffit de soustraire un niveau de hauteur du précédent pour obtenir la différence.

En pseudo-code:

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

Fonctionne en O (n).

17
samgak

Un petit code de golf :) (Basé sur l'excellent samgak explication .)

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

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

En comptant à partir de la fin du tableau, utilisez le dernier élément comme valeur initiale du résultat et comparez le précédent avec celui en cours.

S'ils ont la même valeur, le résultat augmente d'un; si le précédent est plus petit que l'actuel, ne faites rien; si le précédent est plus grand que le courant alors, result = result + previous-current

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;
1
RBB
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;
}
0
Haim Ruso