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 距离间隔重排字符串的更多相关文章

  1. [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 ...

  2. [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 ...

  3. 【LeetCode】1400. 构造 K 个回文字符串 Construct K Palindrome Strings

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计奇数字符出现次数 日期 题目地址:https:// ...

  4. LeetCode初级算法的Python实现--字符串

    LeetCode初级算法的Python实现--字符串 # 反转字符串 def reverseString(s): return s[::-1] # 颠倒数字 def reverse(x): if x ...

  5. RQNOJ 514 字串距离:dp & 字符串

    题目链接:https://www.rqnoj.cn/problem/514 题意: 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字 ...

  6. LeetCode:比较含退格字符串【844】

    LeetCode:比较含退格字符串[844] 题目描述 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = ...

  7. 小b重排字符串

    2485 小b重排字符串 2 秒 262,144 KB 5 分 1 级题   小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab ...

  8. Leetcode 344:Reverse String 反转字符串(python、java)

    Leetcode 344:Reverse String 反转字符串 公众号:爱写bug Write a function that reverses a string. The input strin ...

  9. [链表]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, ...

随机推荐

  1. 040_Eureka 服务注册与发现

    目录 什么是Eureka 原理讲解 Eureka的基本架构 三大角色 盘点目前工程状况 创建Eureka服务端子模块 springcloud-eureka-7001 导入依赖 pom.xml 配置文件 ...

  2. contos配置国内yum源

    contos配置国内yum源 前言 rpm管理软件包的命令,很难用,需要手动解决以来关系,所以最好用 yum 的理念是使用一个中心仓库(repository)管理一部分甚至一个distribution ...

  3. Django的缓存机制和信号

    Django的缓存机制 1.1 缓存介绍 1.缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户 ...

  4. 5月8日 python学习总结 mysql 建表操作

    一 .创建表的完整语法 create table 表名( 字段名1 类型[(宽度) 约束条件],字段名2 类型[(宽度) 约束条件],字段名3 类型[(宽度) 约束条件]); 解释: 类型:使用限制字 ...

  5. 题解0002:Best Cow Fences

    题目描述:给定一个长度为n的正整数序列A.求一个平均数最大的,长度不小于L的子序列,输出这个平均数*1000. 题目链接:http://ybt.ssoier.cn:8088/problem_show. ...

  6. Android 12(S) 图形显示系统 - 解读Gralloc架构及GraphicBuffer创建/传递/释放(十四)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 在前面的文章中,已经出现过 GraphicBuffer 的身影,GraphicBuffer 是Android图形显示系统中的一个重 ...

  7. error C4996: 'std::_Copy_impl'

    以下代码段在VS2008编译可以通过,只是会提示不安全: std::vector<unsigned char> fileData ="asdfsfsfsfsdf";// ...

  8. 比Tensorflow还强?

    大家好,我是章北海 Python是机器学习和深度学习的首选编程语言,但绝不是唯一.训练机器学习/深度学习模型并部署对外提供服务(尤其是通过浏览器)JavaScript 是一个不错的选择,市面上也出现了 ...

  9. Linux的权限总结

    一般权限和特殊权限可控制 文件所有者.所有组.其他人的读写执行权限, 而隐藏权限则可以进行补充权限,可限制 文件内容只能追加内容,不更新属性等信息 ACL则可以进行让某个用户或组或other拥有指定文 ...

  10. Effective Java —— 避免创建不必要的对象

    本文参考 本篇文章参考自<Effective Java>第三版第六条"Avoid creating unnecessary objects" avoid creatin ...