leetcode
leetcode 1301 ~ 1350
点菜展示表

点菜展示表

难度:

标签:

题目描述

代码结果

运行时间: 302 ms, 内存: 26.5 MB


/*
 * 思路:
 * 1. 使用流处理订单数据,创建一个映射来存储桌号及其对应的订单。
 * 2. 收集所有餐品名称并排序。
 * 3. 构建输出的二维数组,第一行是表头,包含 'Table' 和按字母顺序排序的餐品名称。
 * 4. 按桌号顺序填充每张桌子点的餐品数量。
 */

import java.util.*;
import java.util.stream.Collectors;

public class DisplayTableStream {
    public List<List<String>> displayTable(List<List<String>> orders) {
        // 使用流处理订单数据
        Map<String, Map<String, Integer>> tableOrders = orders.stream().collect(
            Collectors.groupingBy(
                order -> order.get(1),
                Collectors.groupingBy(
                    order -> order.get(2),
                    Collectors.summingInt(order -> 1)
                )
            )
        );

        // 收集所有餐品名称并排序
        Set<String> foodItems = orders.stream().map(order -> order.get(2)).collect(Collectors.toSet());
        List<String> sortedFoodItems = new ArrayList<>(foodItems);
        Collections.sort(sortedFoodItems);

        // 构建输出的二维数组
        List<List<String>> display = new ArrayList<>();
        List<String> header = new ArrayList<>();
        header.add("Table");
        header.addAll(sortedFoodItems);
        display.add(header);

        // 按桌号顺序填充每张桌子点的餐品数量
        List<String> sortedTables = tableOrders.keySet().stream().sorted(Comparator.comparingInt(Integer::parseInt)).collect(Collectors.toList());

        for (String table : sortedTables) {
            List<String> row = new ArrayList<>();
            row.add(table);
            Map<String, Integer> foodCount = tableOrders.get(table);
            for (String food : sortedFoodItems) {
                row.add(String.valueOf(foodCount.getOrDefault(food, 0)));
            }
            display.add(row);
        }

        return display;
    }
}

解释

方法:

这个题解采用了哈希表的方法来解决点菜展示表问题。首先使用一个字典 dic1,其中键是桌号,值是另一个Counter,用来统计每张桌子每种食物的数量。另一个字典 set2用来记录每种食物出现在哪些桌号,以方便排序和生成标题行。遍历订单列表,更新这两个字典的信息。之后将食物种类按字典序排序,形成标题行。接着,为每个桌号生成一个数组,数组中包含该桌所有食物的点单数量。最后,将结果列表按桌号排序,并在其前添加标题行。

时间复杂度:

O(F log F + T * F)

空间复杂度:

O(T * F + N)

代码细节讲解

🦆
在题解中,为什么选择使用`defaultdict`和`Counter`作为数据结构来存储订单信息和统计数据?
在题解中使用`defaultdict`和`Counter`可以简化数据记录和统计的操作。`defaultdict`允许自动初始化任何新的键值对,避免了检查和创建新键的额外代码。而`Counter`是专门用于计数的数据结构,可以很方便地对每种食物的点单数量进行累加。这种组合使得算法在处理订单时更加简洁和高效。
🦆
题解中提到对食物种类进行字典序排序,这一排序操作是如何影响最终点菜展示表的输出格式的?
对食物种类进行字典序排序后,食物名称将按照字典顺序出现在点菜展示表的标题行中。这不仅使得最终的展示表在视觉上更有序和一致,也便于用户查找特定食物。排序后的标题行决定了每列数据对应的食物,确保了数据的准确对齐和呈现。
🦆
为什么在处理每张桌子的点菜记录时,选择将桌号和食物名称分别存储在`dic1`和`set2`中,而不是合并为一个单独的字典?
`dic1`和`set2`分别存储不同类型的信息,其中`dic1`存储每张桌子的具体点菜数据(桌号到食物的映射和数量),而`set2`用于记录每种食物出现的所有桌号(食物到桌号的映射),这有助于字典序排序食物名称时快速访问所有相关桌号。这种数据结构的分离使得数据处理更具逻辑性,便于后续的操作如排序和生成显示表。
🦆
题解中提到最终结果列表按桌号排序,这个排序步骤是如何确保所有桌号都正确按数值顺序排列的?
在排序过程中,通过将桌号从字符串形式转换为整型来进行比较,这保证了桌号的排序是按照数值顺序进行的,而不是按照字符串顺序。这对于确保桌号'10'排在'2'之后是必要的,因为在字符串排序中'10'会错误地排在'2'之前。通过这种方式,可以确保最终的展示表中桌号的顺序是正确的。

相关问题