跳转至

1564. 把箱子放进仓库里 I 🔒

题目描述

给定两个正整数数组 boxes 和 warehouse ,分别包含单位宽度的箱子的高度,以及仓库中 n 个房间各自的高度。仓库的房间分别从 0 到 n - 1 自左向右编号, warehouse[i] (索引从 0 开始)是第 i 个房间的高度。

箱子放进仓库时遵循下列规则:

  • 箱子不可叠放。
  • 你可以重新调整箱子的顺序。
  • 箱子只能从左向右推进仓库中。
  • 如果仓库中某房间的高度小于某箱子的高度,则这个箱子和之后的箱子都会停在这个房间的前面。

你最多可以在仓库中放进多少个箱子?

 

示例 1:

输入:boxes = [4,3,4,1], warehouse = [5,3,3,4,1]
输出:3
解释:

我们可以先把高度为 1 的箱子放入 4 号房间,然后再把高度为 3 的箱子放入 1 号、 2 号或 3 号房间,最后再把高度为 4 的箱子放入 0 号房间。
我们不可能把所有 4 个箱子全部放进仓库里。

示例 2:

输入:boxes = [1,2,2,3,4], warehouse = [3,4,1,2]
输出:3
解释:

我们注意到,不可能把高度为 4 的箱子放入仓库中,因为它不能通过高度为 3 的房间。
而且,对于最后两个房间 2 号和 3 号来说,只有高度为 1 的箱子可以放进去。
我们最多可以放进 3 个箱子,如上图所示。黄色的箱子也可以放入 2 号房间。
交换橙色和绿色箱子的位置,或是将这两个箱子与红色箱子交换位置,也是可以的。

示例 3:

输入:boxes = [1,2,3], warehouse = [1,2,3,4]
输出:1
解释:由于第一个房间的高度为 1,我们只能放进高度为 1 的箱子。

 

提示:

  • n == warehouse.length
  • 1 <= boxes.length, warehouse.length <= 10^5
  • 1 <= boxes[i], warehouse[i] <= 10^9

解法

方法一:预处理 + 排序 + 双指针

我们可以先对仓库的房间进行预处理,得到一个数组 $left$,其中 $left[i]$ 表示下标 $i$ 可以放入的最大箱子高度。

然后对箱子的高度进行排序,从小到大依次放入仓库中。我们使用两个指针 $i$ 和 $j$ 分别指向箱子的第一个位置以及仓库的最后一个位置,如果 $left[j] \lt boxes[i]$,说明当前仓库无法放入箱子 $i$,我们将指针 $j$ 循环向左移动,直到 $left[j] \ge boxes[i]$ 或者 $j \lt 0$。如果此时 $j \lt 0$,说明仓库已经没有空间可以放入箱子 $i$,我们可以直接退出循环。否则说明仓库可以放入箱子 $i$,我们将指针 $i$ 循环向右移动,指针 $j$ 循环向左移动。继续进行上述操作,直到指针 $i$ 超出箱子的范围。

最后我们返回指针 $i$ 的值即可。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为仓库的房间数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution:
    def maxBoxesInWarehouse(self, boxes: List[int], warehouse: List[int]) -> int:
        n = len(warehouse)
        left = [warehouse[0]] * n
        for i in range(1, n):
            left[i] = min(left[i - 1], warehouse[i])
        boxes.sort()
        i, j = 0, n - 1
        while i < len(boxes):
            while j >= 0 and left[j] < boxes[i]:
                j -= 1
            if j < 0:
                break
            i, j = i + 1, j - 1
        return i
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
    public int maxBoxesInWarehouse(int[] boxes, int[] warehouse) {
        int n = warehouse.length;
        int[] left = new int[n];
        left[0] = warehouse[0];
        for (int i = 1; i < n; ++i) {
            left[i] = Math.min(left[i - 1], warehouse[i]);
        }
        Arrays.sort(boxes);
        int i = 0, j = n - 1;
        while (i < boxes.length) {
            while (j >= 0 && left[j] < boxes[i]) {
                --j;
            }
            if (j < 0) {
                break;
            }
            ++i;
            --j;
        }
        return i;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
    int maxBoxesInWarehouse(vector<int>& boxes, vector<int>& warehouse) {
        int n = warehouse.size();
        int left[n];
        left[0] = warehouse[0];
        for (int i = 1; i < n; ++i) {
            left[i] = min(left[i - 1], warehouse[i]);
        }
        sort(boxes.begin(), boxes.end());
        int i = 0, j = n - 1;
        while (i < boxes.size()) {
            while (j >= 0 && left[j] < boxes[i]) {
                --j;
            }
            if (j < 0) {
                break;
            }
            ++i;
            --j;
        }
        return i;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
func maxBoxesInWarehouse(boxes []int, warehouse []int) int {
    n := len(warehouse)
    left := make([]int, n)
    left[0] = warehouse[0]
    for i := 1; i < n; i++ {
        left[i] = min(left[i-1], warehouse[i])
    }
    sort.Ints(boxes)
    i, j := 0, n-1
    for i < len(boxes) {
        for j >= 0 && left[j] < boxes[i] {
            j--
        }
        if j < 0 {
            break
        }
        i, j = i+1, j-1
    }
    return i
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
function maxBoxesInWarehouse(boxes: number[], warehouse: number[]): number {
    const n = warehouse.length;
    const left: number[] = new Array(n);
    left[0] = warehouse[0];
    for (let i = 1; i < n; ++i) {
        left[i] = Math.min(left[i - 1], warehouse[i]);
    }
    boxes.sort((a, b) => a - b);
    let i = 0;
    let j = n - 1;
    while (i < boxes.length) {
        while (j >= 0 && left[j] < boxes[i]) {
            --j;
        }
        if (j < 0) {
            break;
        }
        ++i;
        --j;
    }
    return i;
}

评论