【LeetCode】358.K 距离间隔重排字符串
358.K 距离间隔重排字符串
知识点:哈希表;贪心;堆;队列
题目描述
给你一个非空的字符串 s 和一个整数 k,你要将这个字符串中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离至少为 k。
所有输入的字符串都由小写字母组成,如果找不到距离至少为 k 的重排结果,请返回一个空字符串 “”
说明:你不能倾斜容器。
示例

示例 1:
输入: s = "aabbcc", k = 3
输出: "abcabc"
解释: 相同的字母在新的字符串中间隔至少 3 个单位距离。
示例 2:
输入: s = "aaabc", k = 3
输出: ""
解释: 没有办法找到可能的重排结果。
示例 3
输入: s = "aaadbbcc", k = 2
输出: "abacabcd"
解释: 相同的字母在新的字符串中间隔至少 2 个单位距离。
解法一:贪心+队列
这道题应该先对每个字符统计数字,然后应该先插入的是数字最多的字符,这时候需要把这个字符的数量-1,而且应该先把这个字符移出去,因为下一次不能插入它了,必须等长度到达k后才能插入它。
对于插入数字最多的字符,应该排序,所以可以用一个大根堆,堆顶就是数量最多的。
而对于把插入的移出去,可以用队列。
判断队列中的元素个数是否为k,if是的话,那说明对于插入的字符c,它已经间隔够k个字符了,所以c可以再出去一次了,那么久可以把c这个队列头拿出来,放到大根堆里去了。
当大根堆没有元素后,可以判断res的长度,if等于原来的长度,那证明重构完成了,if不等于,那说明有字符还在queue里,重构失败;
class Solution {
public String rearrangeString(String s, int k) {
if (k <= 1) {
return s;
}
HashMap<Character, Integer> map = new HashMap<>();
// 大顶堆
PriorityQueue<Map.Entry<Character, Integer>> maxHeap = new PriorityQueue<>((a, b) -> b.getValue() - a.getValue());
for (Character c : s.toCharArray()) {
// 遍历字符,统计字符的出现次数
map.put(c, map.getOrDefault(c, 0) + 1);
}
maxHeap.addAll(map.entrySet()); // 装入大顶堆,按照字符重复次数作为比较
StringBuilder sb = new StringBuilder(s.length());
Queue<Map.Entry<Character, Integer>> queue = new LinkedList<>();
while (!maxHeap.isEmpty()) {
Map.Entry<Character, Integer> currentEntry = maxHeap.poll(); // 从大顶堆取出重复次数最多的字符
sb.append(currentEntry.getKey());
currentEntry.setValue(currentEntry.getValue() - 1); // 用掉一个字符,次数减一
queue.offer(currentEntry); // 放入到queue中,因为k距离后还要用。
if (queue.size() == k) {
// queue的大小到达了k,也就是说我们已经越过了k个单位,在结果中应该要出现相同的字母了
Map.Entry<Character, Integer> entry = queue.poll();
if (entry.getValue() > 0) {
// 该字符的重复次数大于 0,则添加入大顶堆中,要是0那还加它干嘛
maxHeap.add(entry);
}
}
}
// 退出 while 循环就是大顶堆已经没有元素了,如果此时 sb 的长度没有还原,说明还有元素挂在 queue 中
// 即 queue.size() == k 这个条件没有完全满足,即存在一些字符无法间隔 k 个距离
return sb.length() == s.length() ? sb.toString() : "";
}
}
- python
import heapq
from collections import Counter, deque
class Solution:
def combine_chars(self, input: str, interval: int) -> str:
if interval <= 1:
return input
count = Counter(input) #生成一个字典
heap = [(-v, k) for k, v in count.items()] #按照元祖的第一个即-v来生成小根堆,也就是v的大根堆
heapq.heapify(heap) #生成大根堆
queue = deque() # 队列用来记录已经被记录的字符
res = []
while heap:
count, ch = heapq.heappop(heap)
res.append(ch)
queue.append((count+1, ch))
if len(queue) == interval:
element = queue.popleft()
if element[0] < 0:
heapq.heappush(heap, element)
return "".join(res) if len(res) == len(input) else ""
【LeetCode】358.K 距离间隔重排字符串的更多相关文章
- [LeetCode] 358. Rearrange String k Distance Apart 按距离k间隔重排字符串
Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...
- [Swift]LeetCode358. 按距离为k隔离重排字符串 $ Rearrange String k Distance Apart
Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...
- 【LeetCode】1400. 构造 K 个回文字符串 Construct K Palindrome Strings
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计奇数字符出现次数 日期 题目地址:https:// ...
- LeetCode初级算法的Python实现--字符串
LeetCode初级算法的Python实现--字符串 # 反转字符串 def reverseString(s): return s[::-1] # 颠倒数字 def reverse(x): if x ...
- RQNOJ 514 字串距离:dp & 字符串
题目链接:https://www.rqnoj.cn/problem/514 题意: 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字 ...
- LeetCode:比较含退格字符串【844】
LeetCode:比较含退格字符串[844] 题目描述 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = ...
- 小b重排字符串
2485 小b重排字符串 2 秒 262,144 KB 5 分 1 级题 小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab ...
- Leetcode 344:Reverse String 反转字符串(python、java)
Leetcode 344:Reverse String 反转字符串 公众号:爱写bug Write a function that reverses a string. The input strin ...
- [链表]LeetCode 25 K组一个翻转链表
LeetCode 25 k组一个翻转链表 TITLE 示例 1: 输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5] 示例 2: 输入:head = [1,2,3, ...
随机推荐
- oracle数据库导入导出语句
一.导出: 导出语句: expdp sanyayun/sanyayun@syerpdb directory=DMP dumpfile=fooderp.dmp content=all SCHEMAS=s ...
- isro
靶机准备 将下载的压缩文件解压,打开vmx文件即可 将网络模式设置为NAT 扫描获得ip:192.168.164.185 kali:192.168.164.137 netdiscover -r 192 ...
- 【算法篇】Bitmap 算法
首先,什么是Bitmap算法(位图算法)呢? 一:定义: Bit map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.使用Bit为用来存储数据的单位, 可以大大节省存储空间. ...
- JDBC中大数据量的分页解决方法?
最好的办法是利用sql语句进行分页,这样每次查询出的结果集中就只包含某页的数据内容. sql语句分页,不同的数据库下的分页方案各不一样,下面是主流的三种数据库的分页sql: oracle: selec ...
- Spring 框架中都用到了哪些设计模式?
(1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例: (2)单例模式:Bean默认为单例模式. (3)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB ...
- 讲一讲 kafka 的 ack 的三种机制 ?
request.required.acks 有三个值 0 1 -1(all) 0:生产者不会等待 broker 的 ack,这个延迟最低但是存储的保证最弱当 server 挂 掉的时候就会丢数据. 1 ...
- Mybatis使用拦截器自定义审计处理
void test_save_1(@Param("relatedBookCategoryEntity") RelatedBookCategoryEntity relatedBook ...
- 如何在自定义端口上运行 Spring Boot 应用程序?
为了在自定义端口上运行 Spring Boot 应用程序,您可以在 application.properties 中指定端口. server.port = 8090
- Java 中,嵌套公共静态类与顶级类有什么不同?
类的内部可以有多个嵌套公共静态类,但是一个 Java 源文件只能有一个顶级公 共类,并且顶级公共类的名称与源文件名称必须一致.
- RabbitMQ踩坑记
之前我们给我们的系统加了一个使用SpringAOP+RabbitMQ+WebSocket进行实时消息通知功能(https://www.cnblogs.com/little-sheep/p/993488 ...