前端工程师的 LeetCode 之旅 -- 周赛 185

01

  重新格式化化字符串

题目描述【Easy】

给你一个混合了数字和字母的字符串 s,其中的字母均为小写英文字母。

请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。

请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串 。

示例:

输入:s = 'a0b1c2'

输出:'0a1b2c'

解释:'0a1b2c' 中任意两个相邻字符的类型都不同。'a0b1c2', '0a1b2c', '0c2a1b' 也是满足题目要求的答案。

字符串能否格式化的关键在于:数字与字母的数量之差不能大于 1。

第一步:记录数字和字母各自的数量,并且还需要考虑到后续的字符串的拼接,所以这里采用 JavaScript 中的数组来存储相应的字符。

第二步:如果两种类型字符的数量相差小于 1,那么交叉拼接,优先放入数量较多的类型的字符。

时间复杂度 O(n),空间复杂度 O(n)。

02

 点菜展示表

题目描述【Medium】

给你一个数组 orders,表示客户在餐厅中完成的订单,确切地说, orders[i]=[customerNamei,tableNumberi,foodItemi] ,其中 customerNamei 是客户的姓名,tableNumberi 是客户所在餐桌的桌号,而 foodItemi 是客户点的餐品名称。

请你返回该餐厅的 点菜展示表 。在这张表中,表中第一行为标题,其第一列为餐桌桌号 “Table” ,后面每一列都是按字母顺序排列的餐品名称。接下来每一行中的项则表示每张餐桌订购的相应餐品数量,第一列应当填对应的桌号,后面依次填写下单的餐品数量。

注意:客户姓名不是点菜展示表的一部分。此外,表中的数据行应该按餐桌桌号升序排列。

示例:

输入:orders = [['David','3','Ceviche'],['Corina','10','Beef Burrito'],['David','3','Fried Chicken'],['Carla','5','Water'],['Carla','5','Ceviche'],['Rous','3','Ceviche']]

输出:[['Table','BeefBurrito','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' 

解决本题主要抓住以下要点:

  • 利用 Set 数据结构记录桌号和菜名

  • 利用 Map 数据结构记录每张餐桌订购的相应菜品的数量

  • 桌号按照数字大小升序排列

  • 菜品按照字典序升序排列

时间复杂度 O(n^2),空间复杂度 O(n^2)。

03

 数青蛙

题目描述【Medium】

给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 'croak' )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 'croak' 。请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。

注意:要想发出蛙鸣 'croak',青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。

如果字符串 croakOfFrogs 不是由若干有效的 'croak' 字符混合而成,请返回 -1 。

理解题意之后,主要抓住以下两点:

  • 当遇到 'c' 字符时,需要抓一只青蛙来唱完接下来的字符

  • 当遇到 'k' 字符时,需要释放唱完字符的青蛙

所以接下来的思路就是:利用队列来记录当前唱的字符状态,并且记录当前正在唱歌的青蛙数量。

最终,队列中还有待唱字符,那么该字符串不合法,否则返回最大的青蛙数量。

时间复杂度 O(n^2),空间复杂度 O(n)。

04

  生成数组

题目描述【Hard】

给你三个整数 n、m 和 k 。下图描述的算法用于找出正整数数组中最大的元素。

请你生成一个具有下述属性的数组 arr :

arr 中有 n 个整数。

1 <= arr[i] <= m 其中 (0 <= i < n) 。

将上面提到的算法应用于 arr ,search_cost 的值等于 k 。

返回上述条件下生成数组 arr 的 方法数 ,由于答案可能会很大,所以 必须 对 10^9 + 7 取余。

示例:

输入:n = 2, m = 3, k = 1

输出:6

解释:可能的数组分别为 [1, 1], [2, 1], [2, 2], [3, 1], [3, 2] [3, 3]

首先,要理解本题中的 search_cost 实际上就是最大值的位置。

比较直观的解题方法就是排列枚举所有情况,然后找出满足最大值在 k - 1 位置的方案。

这种方式效率低的原因在于计算了很多重复的情况,所以可以通过动态规划的记忆存储来降低时间复杂度。

在排列枚举的过程,是可以记录当前排列的最大值以及最大值的下标,那么在进行下一位的排列枚举的时候,就可以根据前面的状态计算出相应的数量,而不需要再从头枚举一次。

这里采用动态规划中比较特殊的数位 DP 解决。

05

 往期精彩回顾

你点的每个赞,我都认真当成了喜欢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值