简体   繁体   中英

How would I fix my approach to this Manhattan Skyline/Stone Wall and where did I go wrong? Javascript

I just came across this problem and thought I would give it a try, but now I'm stuck and need help if possible.

The problem I keep facing is my return is usually off by 1 or 2 but I can't figure out why not. I have traced my code back but still can't figure it out

The problem :

You are to write a program to assist an architect in drawing the skyline of a city. Building are rectangular in shape, the height of each building is represented by an element in a given array.

样本图片

The above skyline above is represented like [1,3,2,1,2,1,5,3,3,4,2] 样本图片

SO FAR HERE IS WHAT I AM WORKING WITH:

const skyline =(H)=> {
let stack = [];
let count = 0;
let height = 0;

 const addBlock = (value) => {
    if (value > height) {
        stack.push(value - height);
        height = value;
        count += 1;
    }
 }

 const pop = (value) => {
    while (value < height) {
        height -= stack.pop();
    }  
    if (value > height) {
        addBlock(value)
    }
 }

  for (let i = 0; i < H.length; i += 1) {
    let value = H[i];
    if (value < height) {
        pop(value)
    } else if (value > height) { 
        addBlock(value)
     }
 }

    return count
 }

 skyline([1,3,2,1,2,1,5,3,3,4,2]) //Expect 9

// Test CASES:

let strokes = [1,3,2,1,2,1,5,3,3,4,2] // Expect 9
// let strokes = [5,8] // Expect 8
// let strokes = [1,1,1,1] //  Expect 1

skyline(strokes)

Is this the basic algorithm?

* Big eats small (and equal-sized)

* Small reduces big to small
  adding the difference

* Count last one standing

Examples:

[5,8]
-> 8 eats 5, count 8

[1,1,1,1]
-> 1 eats 1 eats 1 eats 1
-> count 1

[1,3,2,1,2,1,5,3,3,4,2]
-> 3 eats 1
-> 2 reduces 3 to 2 and adds 3-2
-> 1 reduces 2 to 1 and adds 2-1
-> 2 eats 1
-> 1 reduces 2 to 1 and adds 2-1
-> 5 eats 1
-> 3 reduces 5 to 3 and adds 5-3
-> 3 eats 3
-> 4 eats 3
-> 2 reduces 4 to 2 and adds 4-2
-> count 2
Total: 1 + 1 + 1 + 2 + 2 + 2 = 9

JavaScript code:

 function f(A){ let result = 0; for (let i=1; i<A.length; i++) result += Math.max(0, A[i-1] - A[i]); return result + A[A.length-1]; } console.log(f([1,3,2,1,2,1,5,3,3,4,2])); console.log(f([5,8])); console.log(f([1,1,1,1])); 

One liner :)

function f(A){
  return [0].concat(A).reduce((a,b,i,A) => a + Math.max(0, A[i-1] - b)) + A[A.length-1];
}
function minimalNumberOfSkylinesIn(array) {

    if(array.length == 0) 
        return 0;

    let result = array[0];

    for(let i=1; i<array.length; ++i) {
        let differnce = array[i] - array[i-1];
        result += difference > 0 ? difference : 0;
    }

    return result;
}

the current answer seems to solve the problem presented, additionally I would like to point that a way to tackle this kind of problems is to solve it by hand and take notes on which steps you took to solve it.

In this case, they ask you to draw horizontal lines without picking up the pencil and one way to do that by hand is to do all the posible strokes on the same row before passing on to the next, until there are no rows left to check.

On every row, you will surely check if the current spot (array element) is greater than 0, which means that it is part of the stroke.

Now in more concise words:

  1. While there are rowsLeft I will traverse the array. on every traversal I will:
  2. check if the current position is greater than 0 which means there is a newStroke , it also means there are rowsLeft and since you want to keep moving forward you would like to decrease the current element by one.
  3. then, if there is a newStroke and the current element is 0 (end of the stroke) or if it is the end of the array, I would add 1 to my numOfStrokes count and also state that since I have just finished the stroke then there is no newStroke at the moment.

Well that's what I did to solve the case you posted, I believe you can code it from there and I hope it helps you, then again, bruce's answer seems to be right, I just wanted to add how you could came up with the solution, there are surely many ways f doing it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM