问题一
接雨水:https://leetcode-cn.com/problems/trapping-rain-water/
思路:第一次想到的是建立一个n * m的矩阵,有柱子的位置用1表示,没有柱子的位置也就是可能是雨水的用0表示,只要每一行的任何的0两边都被1包夹着,则表示此处接到了雨水,但是oj判断空间和时间都太高了,直接溢出了。换个思路,每次计算每个位置的雨水高度,每个位置的雨水高度取决于左右两边的最高的柱子中,比较低的一侧的柱子。
public int trap(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int result = 0;
// 左右两边无法接到雨水,判断每个位置的雨水能达到的最大高度:即左右两侧的最高的柱子中较小的柱子决定了最大高度
for (int i = 1; i < height.length; i++) {
int maxleft = 0, maxRight = 0;
for (int left = 0; left < i; left++) {
maxleft = maxleft > height[left] ? maxleft : height[left];
}
for (int right = i + 1; right < height.length; right++) {
maxRight = maxRight > height[right] ? maxRight : height[right];
}
int waterHeight = (maxleft > maxRight ? maxRight : maxleft) - height[i];
result = result + (waterHeight >= 0 ? waterHeight : 0);
}
return result;
}
PS:写完看了答案,先从左到右,再从右到左遍历一次数组,计算出每个位置的左侧和右侧的最高的柱子高度,这样可以避免每次都从头遍历一次,时间复杂度可以到O(n)
问题二
动物收容所:https://leetcode-cn.com/problems/animal-shelter-lcci/
思路:保证有顺序的队列就可以,可以使用两个队列,分别存储小猫小狗,这样在dequeue具体类型的动物时,可以避免从头到尾查找。但是相应的在dequeueAny时,需要比较两个队列的第一个动物的编号,来决定具体的出列元素。
class AnimalShelf {
private List<int[]> animals;
public AnimalShelf() {
animals = new LinkedList<>();
}
public void enqueue(int[] animal) {
animals.add(animal);
}
public int[] dequeueAny() {
if (animals.size() == 0) {
return new int[]{-1, -1};
}
return animals.remove(0);
}
public int[] dequeueDog() {
return this.dequeueByType(1);
}
public int[] dequeueCat() {
return this.dequeueByType(0);
}
private int[] dequeueByType(int type) {
for (int i = 0; i < animals.size(); i++) {
int[] animal = animals.get(i);
if (animal[1] == type) {
animals.remove(i);
return animal;
}
}
return new int[]{-1, -1};
}
}