曼哈顿天际线覆盖失败一些测试用例

时间:2014-10-07 04:12:38

标签: java algorithm

我正在做关于贪婪的练习。我花了两天时间来解决这个问题,但我的分数没有提高。我得到了100%的正确性分数,但未通过一些性能测试,因为它返回了错误的答案(不是因为时间或空间的复杂性)。我错误的结果总是低于预期的答案。任何人都可以想到我需要添加一块我缺少的石头吗?

这是提示:

  

你要建造一堵石墙。墙应平直,长N米,厚度应保持不变;但是,它应该在不同的地方有不同的高度。墙的高度由{strong>零索引数组H N正整数指定。

     

H[I]是从左端右侧II+1米的墙的高度。特别是,H[0]是墙的左端高度,H[N−1]是墙右端的高度。

     

墙应该由长方体石块建造(也就是说,这些砌块的所有侧面都是矩形的)。您的任务是计算构建墙所需的最小块数。

     

编写一个函数,给定一个零索引数组H N正整数指定墙的高度,返回构建它所需的最小块数。

class Solution { public int solution(int[] H); }
     

例如,给定的数组H包含N = 9个整数:

  H[0] = 8    H[1] = 8    H[2] = 5    
  H[3] = 7    H[4] = 9    H[5] = 8    
  H[6] = 7    H[7] = 4    H[8] = 8    
     

该函数应返回7.该图显示了七个块的一种可能排列。

     

假设:

     
      
  • N[1..100,000];
  • 范围内的整数   
  • 数组H的每个元素都是[1..1,000,000,000]范围内的整数。
  •   
     

复杂度:

     
      
  • 预期的最坏情况时间复杂度为\ $ O(N)\ $;
  •   
  • 预期的最坏情况空间复杂度为\ $ O(N)\ $,超出输入存储空间(不包括输入参数所需的存储空间)。
  •   
  • 可以修改输入数组的元素。
  •   

这是我的解决方案:

 import java.util.*;

class Solution {
    public int solution(int[] H) {
        // write your code in Java SE 8

        LinkedList<Integer> stack = new LinkedList<Integer>();
        int count = 1;
        int lowest = H[0];
        stack.push(H[0]);

        if(H.length == 1){
            return 1;   
        }
        else{
        for(int i = 1; i<H.length; i++){
            if(H[i] > H[i-1]){
                stack.push(H[i]);
                count++;   
            }
            if(H[i] < lowest){
                while(stack.size() > 0){
                    stack.pop();   
                }
                stack.push(H[i]);
                lowest = H[i];   
                count++;
            }
            if(H[i] < H[i-1] && H[i] > lowest){
                while(stack.size() > 0 && stack.peek() > H[i]){
                    stack.pop();   
                }
                if(stack.size() > 0 && stack.peek() < H[i]){
                    stack.push(H[i]);
                    count++;   
                }
            }
        }
        }

        return count;
    }
}

10 个答案:

答案 0 :(得分:4)

可以发现的一个可能问题是H[i]==lowest时未正确管理Linkedlist。当H[i]==lowest时,程序应该仅使用一个最低块重置Linkedlist。只需将第二个if块更正为:

if(H[i] <= lowest){
    while(stack.size() > 0){
        stack.pop();   
    }
    stack.push(H[i]);                
    if (H[i]!=lowest)
    {
        lowest = H[i];
        count++;
    }
}

考虑案例H = {1,4,3,4,1,4,3,4,1}。正确的输出是7而你的代码返回6。

i is 6时出现问题。第三个if-block重置stack到{3,1}的while循环导致{-1}}出现if-block失败(stack.peek()= H [6] = 3)。

此外,三个if-block可以重写为if-else-if-else-if block,因为H [i]的值只能满足任何i的三个条件之一。

答案 1 :(得分:3)

import java.util.*;

class Solution {
    public int solution(int[] H) {
        Stack<Integer> stack = new Stack<Integer>();
        int count = 1;

        stack.push(H[0]);

        for (int i = 1; i < H.length; i++) {
            if (stack.empty()) {
                stack.push(H[i]);
                count++;
            }
            if (H[i] > stack.peek()) {
                stack.push(H[i]);
                count++;
            }
            while (H[i] < stack.peek()) {
                stack.pop();
                if (stack.empty()) {
                    stack.push(H[i]);
                    count++;
                } else if (H[i] > stack.peek()) {
                    stack.push(H[i]);
                    count++;
                }
            }
        }
        return count;    
    }
}

答案 2 :(得分:2)

我要添加另一个Java Solution 100/100,我添加了自己的Stack类。

https://codility.com/demo/results/demoX7Z9X3-HSB/

以下是代码:

import java.util.ArrayList;
import java.util.List;

public class StoneWall {

      public int solution(int[] H) {
          int len = H.length;
          Stack<Integer> stack = new Stack<>(len);
          int blockCounter = 0;

          for (int i = 0; i < len; ++i) {
              int element = H[i];
              if (stack.isEmpty()) {
                  stack.push(element);
                  ++blockCounter;
              } else {
                  while (!stack.isEmpty() && stack.peek() > element) {
                      stack.pop();
                  } 
                  if (!stack.isEmpty() && stack.peek() == element) {
                     continue;
                  } else {
                      stack.push(element);
                      ++blockCounter;
                  }
              }
          }

          return blockCounter;
      }

      public static class Stack<T> {
          public List<T> stack;

          public Stack(int capacity) {
              stack = new ArrayList<>(capacity);
          }

          public void push(T item) {
              stack.add(item);
          }

          public T pop() {
              T item = peek();
              stack.remove(stack.size() - 1);
              return item;
          }

          public T peek() {
              int position = stack.size();
              T item = stack.get(position - 1);
              return item;
          }

          public boolean isEmpty() {
              return stack.isEmpty();
          }
      }
  }

我们将不胜感激。

答案 3 :(得分:2)

这是@moxi代码的Scala版本:

import scala.collection.mutable


object Solution {
    def solution(H: Array[Int]): Int = {

    val stack =  new mutable.Stack[Int]()

    var blockCounter :Int = 0

    for (i <- 0 to (H.length-1)) {

      var element = H(i)

      if (stack.isEmpty) {
        stack.push(element)
        blockCounter = blockCounter+1
      } else {
        while (!stack.isEmpty && stack.top > element) {
          stack.pop()
        }
        if (!stack.isEmpty && stack.top == element) {

        } else {
          stack.push(element)
          blockCounter = blockCounter+1
        }
      }
    }

    return blockCounter

  }
}

https://codility.com/demo/results/trainingM3BDSK-3YV/

答案 4 :(得分:0)

这是我的100/100 Java解决方案。

public static int solution(int[] H) {
    // write your code in Java SE 8
    Stack<Integer> s = new Stack<Integer>();
    int count = 1;

    for (int i = 0; i < H.length-1; i++) {
        if (H[i + 1] > H[i]) {
            s.push(H[i]);
            count++;
        } else if (H[i + 1] < H[i]) {
            if (s.empty()) {
                s.push(H[i]);
                count++;
            } else if (H[i+1] > s.peek()) {
                count++;
            } else if (H[i+1] < s.peek()) {
                while (!s.empty() && H[i+1] < s.peek()) {
                    s.pop();
                }
                if (s.empty()) {
                    count++;
                } else if (H[i+1] > s.peek()) {
                    count++;
                }
            } else {
                s.pop();
            }
        }
    }
    return count;
}

答案 5 :(得分:0)

老问题;希望它仍然有用。 在FOR循环中的第3个IF语句中,您没有考虑H [i] ==最低的情况。

试试这个:

if(H[i] < H[i-1] && H[i] >= lowest){
    while(stack.size() > 0 && stack.peek() > H[i]){
        stack.pop();   
    }
    if(stack.size() > 0 && stack.peek() < H[i]){
        stack.push(H[i]);
        count++;   
    }
}

另外(但这只是一件小事)使用变量来存储最低值是没有必要的。 通过相应地窥视和弹出,您可以轻松地从堆栈中检索最低值。 此外,您可以使代码更清晰,并避免与堆栈中的头部进行一次比较,一次使用最低值。希望有道理。 这是我的解决方案。

import java.util.Stack;
class Solution {
    public int solution(int[] H) {
        // write your code in Java SE 8
        Stack<Integer> sittingOn = new Stack<Integer>();
        sittingOn.push(H[0]);
        int counter = 1;
        for(int i = 1; i < H.length; i++){ 
            if(sittingOn.peek() < H[i]){
                counter++;
                sittingOn.push(H[i]);
            } 
            else{
                while (!sittingOn.isEmpty() && sittingOn.peek() > H[i]){
                    sittingOn.pop();
                }
                if (sittingOn.isEmpty() || sittingOn.peek() != H[i]){ 
                    sittingOn.push(H[i]);
                    counter++;
                }
            }
        }   
    }        
    return counter;
}

这是我在评论中提到的紧凑版本:

import java.util.Stack;
class Solution {
    public int solution(int[] H) {
        // write your code in Java SE 8
        Stack<Integer> sittingOn = new Stack<Integer>();
        sittingOn.push(H[0]);
        int counter = 1;
        for(int i = 1; i < H.length; i++){ 
            while (!sittingOn.isEmpty() && sittingOn.peek() > H[i]){
                sittingOn.pop();
            }
            if (sittingOn.isEmpty() || sittingOn.peek() != H[i]){ 
                sittingOn.push(H[i]);
                counter++;
            } 
        }   
    }        
    return counter;
}

答案 6 :(得分:0)

我为您提供了Java解决方案,

public int solution(int[] H) {

        Stack<Integer> stack = new Stack<>();

        stack.push(H[0]);
        int count = 1;

        int N = H.length;

        for (int i = 1; i < N; i++) {

            if (H[i] == stack.peek()) {
                continue;
            } else if (H[i] > stack.peek()) {
                stack.push(H[i]);
                count++;
            } else {

                while (!stack.isEmpty() && H[i] < stack.peek()) {
                    stack.pop();
                }

                /*
                 * the new entity is either in same elevation or higher
                 * */

                /*
                * if in same elevation, we already added the block, so keep iterating
                * */
                if (!stack.isEmpty() && H[i] == stack.peek()) {
                    continue;
                }

                stack.push(H[i]);
                count++;
            }
        }

        return count;
    }

在Codility测试中得分为100%。

enter image description here

答案 7 :(得分:0)

这是我的使用堆栈的C ++实现(报告了100%的正确性和性能)。

此逻辑仅执行水平阻塞。

int solution(vector<int> &H) {
    // write your code in C++14 (g++ 6.2.0)
    vector<int> st;
    st.resize(H.size());
    int sp = -1;
    int c = 0;
    for (unsigned i = 0; i < H.size(); ++i) {
        int curElem = H.at(i);
        while (sp != -1) {
            if (curElem >= st[sp])
                break;
            sp--;
        }
        if (sp == -1 || curElem != st[sp]) {
            st[++sp] = curElem;
            c++;
        }
    }
    return c;
}

答案 8 :(得分:0)

function solution(H) {
  let stack=[H[0]];
  let count=0;
  for(let i=1;i<H.length;i++){
    if(H[i]<stack[stack.length-1]){
     count=count+1;
     stack.pop();
     while(stack.length && stack[stack.length-1]>=H[i]){
        if(stack[stack.length-1]>H[i]){
          count=count+1;
          stack.pop();
        }else if(stack[stack.length-1]==H[i]){
          stack.pop();
        }
      }
    stack.push(H[i]);
    
    }else if(H[i]>stack[stack.length-1]){
    stack.push(H[i]);
   }

  }
 return count+stack.length;
}

答案 9 :(得分:0)

我 100% 你可以在这个 link

def solution(H):
   stack =[]

   count = 1

   stack.append(H[0])

   for i in range(1,len(H)):
       if len(stack) == 0:
          stack.append(H[i])
          count+=1
       if H[i] > stack[-1]:
          stack.append(H[i])
          count+=1
       while H[i] < stack[-1]:
          stack.pop()
          if len(stack) == 0:
              stack.append(H[i])
              count+=1
          elif H[i] > stack[-1]:
              stack.append(H[i])
              count+=1

   return count