算法打卡:第6周

问题一

接雨水: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};
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值