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 ...
随机推荐
- NOI2019冬令营报到通知
由中国计算机学会(CCF)主办的2019全国青少年信息学奥林匹克冬令营(CCF NOI 2019冬令营)将于2019年1月24日-31日在广州市第二中学举行.其中1月24日为报到日,1月31日为疏散日 ...
- Animation(动画)倒着播放方法
public GameObject AnimationObj;//带有动画的对象 // Use this for initialization void Start () { AnimationObj ...
- python 笔记数据类型
python基础: 采用缩进方式 4个空格的缩进 大小写敏感 数据类型和变量 数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值,但是,计算机能处理的 ...
- MyEclipse复制js文件乱码
MyEclipse复制js文件乱码 右击js文件:
- jq demo—图片翻页展示效果 animate()动画
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 2.10 C++利用构造函数限制对象的创建
参考: http://www.weixueyuan.net/view/6342.html 总结: 限制对象的创建.限制创建对象时能够按照我们需要的那样创建,而不能随意的创建对象. 类中显示地声明了任意 ...
- 实力封装:Unity打包AssetBundle(二)
→前情提要:Unity最基本的AssetBundle打包方式. 第二种打包方式 Unity提供的BuildAssetBundles API还有一个重载形式,看下面↓↓ public static As ...
- Python如何操作redis
做UI自动化时,遇到一个问题,需要在后台操作完成后,产生结果才能在前端进行操作,但是用自动化在后台操作又很麻烦,就想直接操作数据库,然后再 在前端进行操作:这时遇到一个问题,在后台操作时,会写入到数据 ...
- MySQL:安装mysqld系统及基础应用
MySQL篇 第一章.安装mysqld系统及基础应用 一.安装 注意:mysql的标点符号只能是英文的标点符号. 1.设置配置文件. 文件格式:文本格式 文件位置:Mysql的主目录下 文件名称:my ...
- 调整Windows XP 输入法顺序
執行 Regedit.exe 至 HKEY_CURRENT_USER\Keyboard Layout\Preload 調整輸入法順序,右邊欄中名稱為 1 的鍵值就是內定的輸入法,其值一般為 00000 ...