题目1
给你一个数组 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
范围内的整数。
思路及代码
模拟题,跟着题面写代码就行,这里我用的思路是set来处理可能会重复的菜名和桌号,直接插入以后可以保证得到无重复的菜名和桌号列表,然后一个map<int,map<string,int>> lst;用来存对应桌的对应菜的数量,后面就是输出的问题了。
class Solution {
public:
vector<vector<string>> displayTable(vector<vector<string>>& orders) {
map<int,map<string,int>> lst;
set<string> menu;
set<int> tablelst;
vector<vector<string>> ret;
int len = orders.size();
int tableno;
for(int i = 0;i < len;i++){
tableno = atoi(orders[i][1].c_str());
lst[tableno][orders[i][2]]++;
menu.insert(orders[i][2]);
tablelst.insert(tableno);
}
vector<string> r;
r.push_back("Table");
for(set<string>::iterator it=menu.begin() ;it!=menu.end();it++){
r.push_back(*it);
}
ret.push_back(r);
for(set<int>::iterator it=tablelst.begin() ;it!=tablelst.end();it++){
vector<string> m;
m.push_back(std::to_string(*it));
for(int j = 0;j < menu.size();j++){
m.push_back(std::to_string(lst[*it][r[j+1]]));
}
ret.push_back(m);
m.clear();
}
return ret;
}
};
题目2
我们给出两个单词数组 A
和 B
。每个单词都是一串小写字母。
现在,如果 b
中的每个字母都出现在 a
中,包括重复出现的字母,那么称单词 b
是单词 a
的子集。 例如,“wrr” 是 “warrior” 的子集,但不是 “world” 的子集。
如果对 B
中的每一个单词 b
,b
都是 a
的子集,那么我们称 A
中的单词 a
是通用的。
你可以按任意顺序以列表形式返回 A
中所有的通用单词。
示例 1:
输入:A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"] 输出:["facebook","google","leetcode"]
示例 2:
输入:A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"] 输出:["apple","google","leetcode"]
示例 3:
输入:A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"] 输出:["facebook","google"]
示例 4:
输入:A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"] 输出:["google","leetcode"]
示例 5:
输入:A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"] 输出:["facebook","leetcode"]
提示:
1 <= A.length, B.length <= 10000
1 <= A[i].length, B[i].length <= 10
A[i]
和B[i]
只由小写字母组成。A[i]
中所有的单词都是独一无二的,也就是说不存在i != j
使得A[i] == A[j]
。
思路及代码
这道题花了我四十分钟,现在想想还是没看清题目,首先题目已经说了A中单词独一无二,所以不用对A进行重复处理。但是我最一开始的想法是单写一个函数来判断一个子集问题,事实证明这样会超时,哪怕对B进行去重处理也会超时,于是该思路,先把B全部过一遍,找到所有单词最多所需字母的数量,得到hash表m,然后之后将A里面的所有单词拿来统计字母数并与m比较得到结果。这里用的是unordered_map。对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map。这题我超时了8次,所以这题的优化非常重要!
class Solution {
public:
/*
bool isContent(string a,string b){
map<char,int> m;
char c = 'a';
int alen = a.size();
int blen = b.size();
for(int i = 0;i < alen;i++){
c = a[i];
m[c]++;
}
for(int i = 0;i < blen;i++){
c = b[i];
m[c]--;
if(m[c] < 0){
return false;
}
}
return true;
}
vector<string> wordSubsets(vector<string>& A, vector<string>& B) {
vector<string> ret;
//进行去重处理
sort(B.begin(),B.end());
vector<string>::iterator pos;
pos = unique(B.begin(), B.end());
B.erase(pos, B.end());
bool flag = true;
for(int i = 0;i < A.size();i++){
flag = true;
for(int j = 0;j < B.size();j++){
if(isContent(A[i],B[j]) == false){
flag = false;
break;
}
}
if(flag){
ret.push_back(A[i]);
}
}
return ret;
}
*/
vector<string> wordSubsets(vector<string>& A, vector<string>& B) {
vector<string> ret;
map<char,int> m;
//进行去重处理
sort(B.begin(),B.end());
vector<string>::iterator pos;
pos = unique(B.begin(), B.end());
B.erase(pos, B.end());
for(int j = 0;j < B.size();j++){
char c;
map<char,int> k;
for(int i = 0;i < B[j].size();i++){
c = B[j][i];
k[c]++;
m[c] = max(m[c], k[c]);
}
k.clear();
}
for(int j = 0;j < A.size();j++){
unordered_map<char,int> k;
char c;
for(int i = 0;i < A[j].size();i++){
c = A[j][i];
k[c]++;
}
auto it = m.begin();
for(; it != m.end(); it++)
{
if(k[it->first] >= it->second)
{
}
else
break;
}
if(it == m.end())
{
ret.push_back(A[j]);
}
}
return ret;
}
};
题目3
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
示例 :
输入:[3,2,1,6,0,5] 输出:返回下面这棵树的根节点: 6 / \ 3 5 \ / 2 0 \ 1
提示:
- 给定的数组的大小在 [1, 1000] 之间。
思路及代码
最简单的一题,构造二叉树,直接递归即可,找最大值,然后分左右,然后对左右依次递归,注意退出条件的判断
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size()==0) return NULL;
if(nums.size()==1){
TreeNode * node=new TreeNode(nums[0]);
return node;
}
int max=0;
for(int i=0;i<nums.size();i++){
if(nums[i]>nums[max])
max=i;
}
vector<int> left_num,right_num;
for(int i=0;i<max;i++){
left_num.push_back(nums[i]);
}
for(int j=max+1;j<nums.size();j++){
right_num.push_back(nums[j]);
}
TreeNode * node=new TreeNode(nums[max]);
node->left=constructMaximumBinaryTree(left_num);
node->right=constructMaximumBinaryTree(right_num);
return node;
}
};