【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, ...
随机推荐
- ArcMap操作随记(8)
1.构建两点之间连线 [构造视线] 2.编辑相邻多边形(边界等) [拓扑]工具条→[共享要素] 3.点要素空间分配 [创建泰森多边形]→[裁剪] 4.面要素空间分配 [要素转折点]→[创建泰森多边形] ...
- hadoop学习笔记 一
Hadoop 2.x * common * HDFS 存储数据 NameNode 主从结构 * 存储文件系统的元数据,命名空间namespace DataNode * 存储数据 SecondaryNa ...
- web note
web note html note 列表 ul 无序列表 ol 有序列表 并且可以通过 type 来定义列表序号的形式 <!DOCTYPE html> <html> < ...
- Circle Linux镜像在阿里云镜像站首发上线
镜像下载.域名解析.时间同步请点击阿里云开源镜像站 Circle Linux简介 Circle Linux 社区是一个开源.共创的 Linux 社区,将通过完全开放.包容的社区形式与全球开发者共同构建 ...
- ArcMap连接oracle、oracle配置
服务器:Oracle 11g 客户端:arcgis desktop 10.4.1.oracle 11g 32位客户端 客户端:arcgis server 10.4.1.oracle 11g 64位客户 ...
- sql注入之简要注入
#mysql简要注入流程 mysql注入简要流程如下图: 由于还没学习完先结合sqlilabs的第一关讲解信息收集的一部分和数据注入的information_schema的有据查询. #sqli-la ...
- 使用VS Code编译Marlin固件
参考:https://marlinfw.org/docs/basics/install_platformio_vscode.html 前言 在阅读本文之前,您应该已经阅读了使用 PlatformIO ...
- eureka自我保护机制是什么?
当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式.
- MySQL安装速成指南(ZIP)
MySQL初始化数据库 第一步:将MySQL ZIP压缩包进行解压 第二部:在MySQL主目录创建my.ini文件,并添加以下内容 [client] port=3306 socket=/tmp/mys ...
- 分布式存储---FastDFS+GlusterFS
一. 存储概念 1.块存储的多种实现: 块存储: 就好比硬盘一样, 直接挂在到主机,一般用于主机的直接存储空间和数据库应用的存储 1.磁盘+LVS: 单机硬盘纯存储 2.DAS(DELL MD系列): ...