Манхэттенский горизонт обложки, в котором отсутствуют некоторые тестовые примеры

90
10

Я занимаюсь упражнениями на кодовости. Я потратил два дня на эту проблему, не улучшив свою оценку. Я получаю 100% от оценки правильности, но не выполняю некоторые тесты производительности, потому что он возвращает неправильный ответ (не из-за сложности времени или пространства). Мои неправильные результаты всегда меньше ожидаемого ответа. Может ли кто-нибудь подумать о случае, когда мне нужно добавить камень, который мне не хватает?


Это подсказка:


Вы собираетесь построить каменную стену. Стена должна быть прямой и длиной N метров, а ее толщина должна быть постоянной; однако он должен иметь разную высоту в разных местах. Высота стены определяется нулевым индексом массивом H N положительных целых чисел.

H[I] - высота стены от I до I+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;
}
}

спросил(а) 2014-10-07T07:12:00+04:00 5 лет, 11 месяцев назад
1
Решение
91

Одна возможная проблема, которая может быть обнаружена, связана с тем, что Linkedlist неправильно управляется при H[i]==lowest. Если H[i]==lowest, программа должна reset связанного списка только с одним самым низким блоком. Просто исправьте второй 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. Цикл while в третьем if-блоке reset stack до {3,1}, что приводит к stack.peek() < H[i] при следующем отказе if-блока (stack.peek() = H [6] = 3).


Кроме того, три if-блока могут быть переписаны как блок if-else-if-else-if, так как значение H [i] может соответствовать одному из трех условий только для любого i.

ответил(а) 2014-10-07T10:58:00+04:00 5 лет, 11 месяцев назад
80

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

ответил(а) 2014-12-03T20:05:00+03:00 5 лет, 9 месяцев назад
69

Здесь Scala версия кода @moxi:


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/

ответил(а) 2015-10-18T19:13:00+03:00 4 года, 11 месяцев назад
70

Я собираюсь добавить еще одно 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();
}
}
}


Любая обратная связь будет оценена.

ответил(а) 2015-08-14T09:25:00+03:00 5 лет, 1 месяц назад
40

Старый вопрос; надеюсь, это будет по-прежнему полезно.
В вашей третьей инструкции IF в цикле FOR вы не рассматриваете случай, когда 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;
}

ответил(а) 2016-03-09T14:25:00+03:00 4 года, 6 месяцев назад
41

Это мое решение 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;
}

ответил(а) 2016-01-25T07:27:00+03:00 4 года, 8 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема