LeetCode - Reorganize String
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same. If possible, output any possible result. If not possible, return the empty string. Example 1: Input: S = "aab"
Output: "aba"
Example 2: Input: S = "aaab"
Output: ""
Note: S will consist of lowercase letters and have length in range [1, 500].
这道题给了我们一个字符串,让我们重构这个字符串,使得相同的字符不会相邻,如果无法做到,那么就返回空串,题目中的例子很好的说明了这一点。那么,如果先不考虑代码实现,让你来手动重构的话,该怎么做呢?我们要做的就是把相同的字符分开。比如例子1中,两个a相邻了,所以我们把第二个a和后面的b交换位置,这样分开了相同的字符,就是最终答案了。我们再来看一个例子,比如"aaabbc",那么其实我们发现第二个字符也是‘a’的时候,就需要往后遍历找到第一个不是‘a’的字符,即‘b’,然后交换‘a’和‘b’即可,然后继续往后面进行同样的处理,当无法找到不同的字符后就返回空串。这种方法对有序的字符串S是可以的,虽然题目给的两个例子中字符串S都是有序的,实际上不一定是有序的。所以博主最先的想法是给数组排序呗,但是博主的这个解法跪在了这个例子上"vvvlo",我们发现排序后就变成"lovvv",这样上面提到的解法就跪了。我们希望次数出现多的字符串再前面,这样才好交换嘛。那么我们还是要统计每个字符串出现的次数啊,这里使用HashMap来建立字母和其出现次数之间的映射。由于我们希望次数多的字符排前面,可以使用一个最大堆,C++中就是优先队列Priority Queue,将次数当做排序的key,那么就把次数和其对应的字母组成一个pair,放进最大堆中自动排序。这里其实有个剪枝的trick,如果某个字母出现的频率大于总长度的一半了,那么必然会有两个相邻的字母出现。这里博主就不证明了,感觉有点像抽屉原理。所以我们在将映射对加入优先队列时,先判断下次数,超过总长度一半了的话直接返回空串就行了。
好,我们的最大堆建立好以后,我们想,此时难道还是应该使用上面所说的交换的方法吗?其实直接构建新的字符串要更加简单一些。接下来,我们每次从优先队列中取队首的两个映射对儿处理,因为我们要拆开相同的字母,这两个映射对儿肯定是不同的字母,我们可以将其放在一起,之后我们需要将两个映射对儿中的次数自减1,如果还有多余的字母,即减1后的次数仍大于0的话,将其再放回最大堆。由于我们是两个两个取的,所以最后while循环退出后,有可能优先队列中还剩下了一个映射对儿,此时将其加入结果res即可。而且这个多余的映射对儿一定只有一个字母了,因为我们提前判断过各个字母的出现次数是否小于等于总长度的一半,按这种机制来取字母,不可能会剩下多余一个的相同的字母.
这道题我之前不明白的是为什么一定要使用priorityQueue最大堆来做,后来写完之后才明白, 如果不用最大堆,可能会出现最后存在的那个映射和前一个是一样,列子“aab”.
注意map, priorityqueue的各种方法
class Solution {
public String reorganizeString(String S) {
if(S == null || S.length() == 0){
return "";
}
Map<Character, Integer> map = new HashMap<>();
for(char c: S.toCharArray()){
map.put(c, map.getOrDefault(c,0)+1);
}
//anonymous class
PriorityQueue<Map.Entry<Character, Integer>> pq = new PriorityQueue<>(new Comparator<Map.Entry<Character, Integer>>() {
public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
//pq.addAll(map.entrySet());
for(Map.Entry<Character, Integer> entry : map.entrySet()){
if(entry.getValue() > (S.length()+1)/2){
return "";
}
pq.add(entry);
}
StringBuilder sb = new StringBuilder();
while(pq.size() > 1){
Map.Entry<Character, Integer> entry1 = pq.poll();
Map.Entry<Character, Integer> entry2 = pq.poll();
sb.append(entry1.getKey());
sb.append(entry2.getKey());
if(entry1.getValue() -1 > 0){
entry1.setValue(entry1.getValue() -1);
pq.add(entry1);
}
if(entry2.getValue() -1 > 0){
entry2.setValue(entry2.getValue() -1);
pq.add(entry2);
}
}
if(pq.size() > 0){
sb.append(pq.poll().getKey());
}
return sb.toString();
}
}
LeetCode - Reorganize String的更多相关文章
- [LeetCode] Reorganize String 重构字符串
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- [leetcode]Weekly Contest 68 (767. Reorganize String&&769. Max Chunks To Make Sorted&&768. Max Chunks To Make Sorted II)
766. Toeplitz Matrix 第一题不说,贼麻瓜,好久没以比赛的状态写题,这个题浪费了快40分钟,我真是...... 767. Reorganize String 就是给你一个字符串,能不 ...
- 767. Reorganize String - LeetCode
Question 767. Reorganize String Solution 题目大意: 给一个字符串,将字符按如下规则排序,相邻两个字符一同,如果相同返回空串否则返回排序后的串. 思路: 首先找 ...
- LeetCode——Reverse String
LeetCode--Reverse String Question Write a function that takes a string as input and returns the stri ...
- Leetcode 8. String to Integer (atoi) atoi函数实现 (字符串)
Leetcode 8. String to Integer (atoi) atoi函数实现 (字符串) 题目描述 实现atoi函数,将一个字符串转化为数字 测试样例 Input: "42&q ...
- 767. Reorganize String
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- [LeetCode] 767. Reorganize String 重构字符串
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- 【LeetCode】767. Reorganize String 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.me/ 题目地址:https://leetcode.com/problems/reorganiz ...
- LeetCode - 767. Reorganize String
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
随机推荐
- UVa 11039 - Building designing 贪心,水题 难度: 0
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- 架构之路:nginx与IIS服务器搭建集群实现负载均衡(三)
参考网址:https://blog.csdn.net/zhanghan18333611647/article/details/50811980 [前言] 在<架构之路:nginx与IIS服务器搭 ...
- weblogic部署web项目(war包)
第一步,启动并访问weblogic,进入登录页面 第二步,进入主页面,开始部署项目 第三步,上载项目war包 选择需要上载的本地war包 第四步,开始项目配置 继续下一步 选择红色标记的配置 第五步, ...
- ppt点击文字出现图片,再次点击消失
实现效果:在PPT一个页面的任意位置,单击左键,出现图片:在图片上,单击左键,图片消失 实现思路:给图片做两个动画,一个进入,文字作触发器,另一个退出,图片本身为触发器. 实现方法: 1.选中图片…… ...
- PHP和Mysql事物处理
这几天做支付的时候,又用到了事物,为了方便自己以后查看,今天闲的没事就把以前的东西整理下.(其中引用别人的东西,在这里谢谢他们贡献的代码!) 一.事务处理概述: 事务:是若干事件的集合 事务处理:当所 ...
- 不同生产商的CPU以及大端/小端对齐
● 不同生产商的CPU以及大端/小端对齐 ※ ARM.AMD.Atom和intel之间的关系 intel公司和AMD公司生产的是相同的x86架构的CPU,这种CPU属于CISC(Complex I ...
- JS日期工具类(转)
javascript Date format(js日期格式化) https://www.cnblogs.com/zhangpengshou/archive/2012/07/19/2599053.htm ...
- innerHTML和innerText的区别,以及select元素中怎么取出被选中的option。
一.innerHTML和innerText的区别. 元素.innerHTML = 字符串,是将一对或一个标签所标识的内容全部替换为所赋予的字符串,如果字符串中有标签,浏览器将自动识别其中的标签. 元素 ...
- Docker(2):快速入门及常用命令
什么是Docker? Docker 是世界领先的软件容器平台.开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题.运维人员利用 Docker 可以在隔离容器中并行运行和管理 ...
- ubuntu apache ssl配置
参考连接: http://blog.csdn.net/sky_qing/article/details/44303221 http://blog.sina.com.cn/s/blog_6ad62438 ...