最长快乐字符串(2022-2-7)每日一练

1405. 最长快乐字符串(2022-2-7)

如果字符串中不含有任何 'aaa''bbb''ccc' 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。

给你三个整数 abc,请你返回 任意一个 满足下列全部条件的字符串 s

  • s 是一个尽可能长的快乐字符串。
  • s最多a 个字母 'a'b 个字母 'b'c 个字母 'c'
  • s中只含有 'a''b''c' 三种字母。

如果不存在这样的字符串 s ,请返回一个空字符串 ""

示例 1:

输入:a = 1, b = 1, c = 7
输出:“ccaccbcc”
解释:“ccbccacc” 也是一种正确答案。

解题思路

Object.entries():方法返回一个给定对象自身可枚举属性的键值对数组。类似于用了for in
MDN文档

这道题其实很容易看懂,无非就是贪心的思想,找到剩余数量最多的字符,去拼接到目标字符串上。

  • 本题的第一个难点在于,将a,b,c进行排序,而且要始终维持一个降序的排列,起初我用的是一个字面量对象来表示{a : a}字符与数量的关系,但是没法排序,看官方题解发现,用数组表示,其实更容易处理[[a,'a'],[b,'b']],还可以直接用sort()排序。

  • 通常我们默认会将字符两个两个的去拼接(因为是最优嘛),当不够一个的时候才拼接一个字符,其实这是个坑。因为两个两个去拼接,必定会剩下单数个,而这表明,两个两个拼接并不是局部最优(会错失正确答案例如7,2,2)。

  • 我们换个思路,一个一个的去拼接,每次拼接的都是数量最多的字符,如果目标字符串中已经重复出现了两次,那么再拼接数量次多的字符。这样子代码也会更加好写,能少一些没必要的判断,更容易理解。

下面是我参照官方题解写的代码:

var longestDiverseString = function(a, b, c) {
  const source = [[a,'a'],[b,'b'],[c,'c']]
  let res = []
	while(1){
  	source.sort((a,b)=> b[0] - a[0])
  	let next = false
  	for(let [i,[c,ch]] of source.entries()){
  		if(c == 0) break
  		let len = res.length
  		if(len >= 2 && res[len-1] == ch && res[len-2] == ch) continue
  		res.push(ch)
  		next = true
  		source[i][0]--
  		break
  	}
  	if(!next) break
  }
  return res.join('')
};

还有一种大顶堆的写法,用优先队列来维系降序的字符关系,我觉得有些大材小用了(太麻烦了)。

在这里附上优先队列的过程:

优先队列-1
请添加图片描述

遇到不会的题,想不到的题很正常,关键在于下次是否想得到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值