哈希表
字符串
排序
数组
有序集合
题目描述
给你一个数组 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\) 分别表示菜品种类数和餐桌数。
Python3 Java C++ Go TypeScript
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 ;
}
GitHub