我正在做关于贪婪的练习。我花了两天时间来解决这个问题,但我的分数没有提高。我得到了100%的正确性分数,但未通过一些性能测试,因为它返回了错误的答案(不是因为时间或空间的复杂性)。我错误的结果总是低于预期的答案。任何人都可以想到我需要添加一块我缺少的石头吗?
这是提示:
你要建造一堵石墙。墙应平直,长N米,厚度应保持不变;但是,它应该在不同的地方有不同的高度。墙的高度由{strong>零索引数组
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;
}
}
答案 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
}
}
答案 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)
试试这个:
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%。
答案 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