题目描述
给你一个数组 orders
,表示客户在餐厅中完成的订单,确切地说, orders[i]=[customerNamei,tableNumberi,foodItemi]
,其中 customerNamei
是客户的姓名,tableNumberi
是客户所在餐桌的桌号,而 foodItemi
是客户点的餐品名称。
请你返回该餐厅的 点菜展示表 。在这张表中,表中第一行为标题,其第一列为餐桌桌号 “Table” ,后面每一列都是按字母顺序排列的餐品名称。接下来每一行中的项则表示每张餐桌订购的相应餐品数量,第一列应当填对应的桌号,后面依次填写下单的餐品数量。
注意:客户姓名不是点菜展示表的一部分。此外,表中的数据行应该按餐桌桌号升序排列。
示例 1:
输入:orders = [["David","3","Ceviche"],["Corina","10","Beef Burrito"],["David","3","Fried Chicken"],["Carla","5","Water"],["Carla","5","Ceviche"],["Rous","3","Ceviche"]]
输出:[["Table","Beef Burrito","Ceviche","Fried Chicken","Water"],["3","0","2","1","0"],["5","0","1","0","1"],["10","1","0","0","0"]]
解释:
点菜展示表如下所示:
Table,Beef Burrito,Ceviche,Fried Chicken,Water
3 ,0 ,2 ,1 ,0
5 ,0 ,1 ,0 ,1
10 ,1 ,0 ,0 ,0
对于餐桌 3:David 点了 "Ceviche" 和 "Fried Chicken",而 Rous 点了 "Ceviche"
而餐桌 5:Carla 点了 "Water" 和 "Ceviche"
餐桌 10:Corina 点了 "Beef Burrito"
示例 2:
输入:orders = [["James","12","Fried Chicken"],["Ratesh","12","Fried Chicken"],["Amadeus","12","Fried Chicken"],["Adam","1","Canadian Waffles"],["Brianna","1","Canadian Waffles"]]
输出:[["Table","Canadian Waffles","Fried Chicken"],["1","2","0"],["12","0","3"]]
解释:
对于餐桌 1:Adam 和 Brianna 都点了 "Canadian Waffles"
而餐桌 12:James, Ratesh 和 Amadeus 都点了 "Fried Chicken"
示例 3:
输入:orders = [["Laura","2","Bean Burrito"],["Jhon","2","Beef Burrito"],["Melissa","2","Soda"]]
输出:[["Table","Bean Burrito","Beef Burrito","Soda"],["2","1","1","1"]]
提示:
1 <= orders.length <= 5 * 10^4
orders[i].length == 3
1 <= customerNamei.length, foodItemi.length <= 20
customerNamei
和 foodItemi
由大小写英文字母及空格字符 ' '
组成。
tableNumberi
是 1
到 500
范围内的整数。
解法
方法一:哈希表 + 排序
我们可以用一个哈希表 $\textit{tables}$ 来存储每张餐桌点的菜品,用一个集合 $\textit{items}$ 来存储所有的菜品。
遍历 $\textit{orders}$,将每张餐桌点的菜品存入 $\textit{tables}$ 和 $\textit{items}$ 中。
然后我们将 $\textit{items}$ 排序,得到 $\textit{sortedItems}$。
接下来,我们构建答案数组 $\textit{ans}$,首先将标题行 $\textit{header}$ 加入 $\textit{ans}$,然后遍历排序后的 $\textit{tables}$,对于每张餐桌,我们用一个计数器 $\textit{cnt}$ 来统计每种菜品的数量,然后构建一行 $\textit{row}$,将其加入 $\textit{ans}$。
最后返回 $\textit{ans}$。
时间复杂度 $O(n + m \times \log m + k \times \log k + m \times k)$,空间复杂度 $O(n + m + k)$。其中 $n$ 是数组 $\textit{orders}$ 的长度,而 $m$ 和 $k$ 分别表示菜品种类数和餐桌数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | class Solution:
def displayTable(self, orders: List[List[str]]) -> List[List[str]]:
tables = defaultdict(list)
items = set()
for _, table, foodItem in orders:
tables[int(table)].append(foodItem)
items.add(foodItem)
sorted_items = sorted(items)
ans = [["Table"] + sorted_items]
for table in sorted(tables):
cnt = Counter(tables[table])
row = [str(table)] + [str(cnt[item]) for item in sorted_items]
ans.append(row)
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | class Solution {
public List<List<String>> displayTable(List<List<String>> orders) {
TreeMap<Integer, List<String>> tables = new TreeMap<>();
Set<String> items = new HashSet<>();
for (List<String> o : orders) {
int table = Integer.parseInt(o.get(1));
String foodItem = o.get(2);
tables.computeIfAbsent(table, k -> new ArrayList<>()).add(foodItem);
items.add(foodItem);
}
List<String> sortedItems = new ArrayList<>(items);
Collections.sort(sortedItems);
List<List<String>> ans = new ArrayList<>();
List<String> header = new ArrayList<>();
header.add("Table");
header.addAll(sortedItems);
ans.add(header);
for (Map.Entry<Integer, List<String>> entry : tables.entrySet()) {
Map<String, Integer> cnt = new HashMap<>();
for (String item : entry.getValue()) {
cnt.merge(item, 1, Integer::sum);
}
List<String> row = new ArrayList<>();
row.add(String.valueOf(entry.getKey()));
for (String item : sortedItems) {
row.add(String.valueOf(cnt.getOrDefault(item, 0)));
}
ans.add(row);
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | class Solution {
public:
vector<vector<string>> displayTable(vector<vector<string>>& orders) {
map<int, vector<string>> tables;
set<string> sortedItems;
for (auto& o : orders) {
int table = stoi(o[1]);
string foodItem = o[2];
tables[table].push_back(foodItem);
sortedItems.insert(foodItem);
}
vector<vector<string>> ans;
vector<string> header = {"Table"};
header.insert(header.end(), sortedItems.begin(), sortedItems.end());
ans.push_back(header);
for (auto& [table, items] : tables) {
unordered_map<string, int> cnt;
for (string& item : items) {
cnt[item]++;
}
vector<string> row;
row.push_back(to_string(table));
for (const string& item : sortedItems) {
row.push_back(to_string(cnt[item]));
}
ans.push_back(row);
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | func displayTable(orders [][]string) [][]string {
tables := make(map[int]map[string]int)
items := make(map[string]bool)
for _, order := range orders {
table, _ := strconv.Atoi(order[1])
foodItem := order[2]
if tables[table] == nil {
tables[table] = make(map[string]int)
}
tables[table][foodItem]++
items[foodItem] = true
}
sortedItems := make([]string, 0, len(items))
for item := range items {
sortedItems = append(sortedItems, item)
}
sort.Strings(sortedItems)
ans := [][]string{}
header := append([]string{"Table"}, sortedItems...)
ans = append(ans, header)
tableNums := make([]int, 0, len(tables))
for table := range tables {
tableNums = append(tableNums, table)
}
sort.Ints(tableNums)
for _, table := range tableNums {
row := []string{strconv.Itoa(table)}
for _, item := range sortedItems {
count := tables[table][item]
row = append(row, strconv.Itoa(count))
}
ans = append(ans, row)
}
return ans
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | function displayTable(orders: string[][]): string[][] {
const tables: Record<number, Record<string, number>> = {};
const items: Set<string> = new Set();
for (const [_, table, foodItem] of orders) {
const t = +table;
if (!tables[t]) {
tables[t] = {};
}
if (!tables[t][foodItem]) {
tables[t][foodItem] = 0;
}
tables[t][foodItem]++;
items.add(foodItem);
}
const sortedItems = Array.from(items).sort();
const ans: string[][] = [];
const header: string[] = ['Table', ...sortedItems];
ans.push(header);
const sortedTableNumbers = Object.keys(tables)
.map(Number)
.sort((a, b) => a - b);
for (const table of sortedTableNumbers) {
const row: string[] = [table.toString()];
for (const item of sortedItems) {
row.push((tables[table][item] || 0).toString());
}
ans.push(row);
}
return ans;
}
|