【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, ...
随机推荐
- 040_Eureka 服务注册与发现
目录 什么是Eureka 原理讲解 Eureka的基本架构 三大角色 盘点目前工程状况 创建Eureka服务端子模块 springcloud-eureka-7001 导入依赖 pom.xml 配置文件 ...
- contos配置国内yum源
contos配置国内yum源 前言 rpm管理软件包的命令,很难用,需要手动解决以来关系,所以最好用 yum 的理念是使用一个中心仓库(repository)管理一部分甚至一个distribution ...
- Django的缓存机制和信号
Django的缓存机制 1.1 缓存介绍 1.缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户 ...
- 5月8日 python学习总结 mysql 建表操作
一 .创建表的完整语法 create table 表名( 字段名1 类型[(宽度) 约束条件],字段名2 类型[(宽度) 约束条件],字段名3 类型[(宽度) 约束条件]); 解释: 类型:使用限制字 ...
- 题解0002:Best Cow Fences
题目描述:给定一个长度为n的正整数序列A.求一个平均数最大的,长度不小于L的子序列,输出这个平均数*1000. 题目链接:http://ybt.ssoier.cn:8088/problem_show. ...
- Android 12(S) 图形显示系统 - 解读Gralloc架构及GraphicBuffer创建/传递/释放(十四)
必读: Android 12(S) 图形显示系统 - 开篇 一.前言 在前面的文章中,已经出现过 GraphicBuffer 的身影,GraphicBuffer 是Android图形显示系统中的一个重 ...
- error C4996: 'std::_Copy_impl'
以下代码段在VS2008编译可以通过,只是会提示不安全: std::vector<unsigned char> fileData ="asdfsfsfsfsdf";// ...
- 比Tensorflow还强?
大家好,我是章北海 Python是机器学习和深度学习的首选编程语言,但绝不是唯一.训练机器学习/深度学习模型并部署对外提供服务(尤其是通过浏览器)JavaScript 是一个不错的选择,市面上也出现了 ...
- Linux的权限总结
一般权限和特殊权限可控制 文件所有者.所有组.其他人的读写执行权限, 而隐藏权限则可以进行补充权限,可限制 文件内容只能追加内容,不更新属性等信息 ACL则可以进行让某个用户或组或other拥有指定文 ...
- Effective Java —— 避免创建不必要的对象
本文参考 本篇文章参考自<Effective Java>第三版第六条"Avoid creating unnecessary objects" avoid creatin ...