LeetCode 1405. Longest Happy String - 优先级队列(Priority Queue)系列题9

A string s is called happy if it satisfies the following conditions:

  • s only contains the letters 'a''b', and 'c'.
  • s does not contain any of "aaa""bbb", or "ccc" as a substring.
  • s contains at most a occurrences of the letter 'a'.
  • s contains at most b occurrences of the letter 'b'.
  • s contains at most c occurrences of the letter 'c'.

Given three integers ab, and c, return the longest possible happy string. If there are multiple longest happy strings, return any of them. If there is no such string, return the empty string "".

substring is a contiguous sequence of characters within a string.

Example 1:

Input: a = 1, b = 1, c = 7
Output: "ccaccbcc"
Explanation: "ccbccacc" would also be a correct answer.

Example 2:

Input: a = 7, b = 1, c = 0
Output: "aabaa"
Explanation: It is the only correct answer in this case.

Constraints:

  • 0 <= a, b, c <= 100
  • a + b + c > 0

题目说一个字符串s可以被称为快乐字符串需要满足以下条件:

  • s 只含有字母 'a''b', and 'c'.
  • s 中相同字母连续不超过2个,即不含有任何"aaa""bbb", or "ccc" 子字符串.
  • s 包含字母 'a'个数最多不超过整数a.
  • s 包含字母 'b'.个数最多不超过整数b
  • s 包含字母 'c'个数最多不超过整数c

现在给定3个整数a,b和c,要求返回由它们组成的最长的欢乐字符串。

解题思路:属于重组字符串的题,跟767. Reorganize String有一点像,原则是使相同字母每隔一个位置放两个使得连续的相同字母不超过2个,另外本着在前面尽可能地多取字母放入字符串的原则,因此每次要从个数最多的字母中(如果大于两个的话)取出两个放入字符串中,紧随其后应该取其它的字母这样才不至于连续相同字母大于等于3,那其它字母应该取一个还是两个呢?还是本着尽可能优先处理字母个数最多的字母的原则,如果第一次被取走2个的字母剩下个数还是最多的,那么就从第二多的字母中取出一个放入字符串以做隔离以便下次还是取2个最多的字母;如果第一次被取走2个的字母剩下个数就不是最多的了,那么原来第二多的就变成最多的了,那就应该取出2个放入字符串中。如此循环下去,当字母种类只剩一种时就应该停止循序,最后再放入2个剩下的字母。这样组成的字符串就是最长的。

class MyChar:
    def __init__(self, c, n):
        self.c = c
        self.n = n
    def __lt__(self, other):
        return self.n > other.n
    
class Solution:
    def longestDiverseString(self, a: int, b: int, c: int) -> str:
        pq = []
        if a > 0:
            heapq.heappush(pq, MyChar('a', a))
        if b > 0:
            heapq.heappush(pq, MyChar('b', b))
        if c > 0:
            heapq.heappush(pq, MyChar('c', c))
        
        res = []
        while len(pq) > 1:
            c1 = heapq.heappop(pq)
            res.append(c1.c)
            c1.n -= 1
            if c1.n > 0:
                res.append(c1.c)
                c1.n -= 1
            c2 = heapq.heappop(pq)
            if c1.n >= c2.n:
                res.append(c2.c)
                c2.n -= 1
            if c1.n > 0:
                heapq.heappush(pq, c1)
            if c2.n > 0:
                heapq.heappush(pq, c2)
        while len(pq) > 0:
            c1 = heapq.heappop(pq)
            res.append(c1.c)
            c1.n -= 1
            if c1.n > 0:
                res.append(c1.c)
            break
        
        return ''.join(res)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于LeetCode上的问994.腐烂的橘子,你可以使用Python来解决。下面是一个示例代码: ```python from collections import deque def orangesRotting(grid): # 记录网格的行数和列数 row, col = len(grid), len(grid[0]) # 定义四个方向:上、下、左、右 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 使用队列来保存腐烂的橘子的位置 queue = deque() # 记录新鲜橘子的数量 fresh_count = 0 # 遍历整个网格,初始化队列和新鲜橘子的数量 for i in range(row): for j in range(col): if grid[i][j] == 2: # 腐烂的橘子 queue.append((i, j)) elif grid[i][j] == 1: # 新鲜橘子 fresh_count += 1 # 如果新鲜橘子的数量为0,直接返回0 if fresh_count == 0: return 0 # 初始化分钟数 minutes = 0 # 开始进行BFS,直到队列为空 while queue: # 记录当前分钟数下,队列中的元素数量 size = len(queue) # 遍历当前分钟数下的所有腐烂的橘子 for _ in range(size): x, y = queue.popleft() # 遍历四个方向 for dx, dy in directions: nx, ny = x + dx, y + dy # 判断新位置是否在网格内,并且是新鲜橘子 if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1: # 将新鲜橘子变为腐烂状态 grid[nx][ny] = 2 # 将新鲜橘子的位置加入队列 queue.append((nx, ny)) # 新鲜橘子的数量减1 fresh_count -= 1 # 如果当前分钟数下,没有新鲜橘子了,结束循环 if fresh_count == 0: break # 每遍历完一层,分钟数加1 minutes += 1 # 如果最后还有新鲜橘子,返回-1,否则返回分钟数 return -1 if fresh_count > 0 else minutes ``` 你可以将给定的网格作为参数传递给`orangesRotting`函数来测试它。请注意,该代码使用了BFS算法来遍历橘子,并计算腐烂的分钟数。希望能对你有所帮助!如果有任何疑问,请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值