leetcode题解-451. Sort Characters By Frequency
2017-03-02 15:47
357 查看
题目:Given a string, sort it in decreasing order based on the frequency of characters.
Example 1: Input: “tree” Output: “eert”
Explanation: ‘e’ appears twice while ‘r’ and ‘t’ both appear once. So ‘e’ must appear before both ‘r’ and ‘t’. Therefore “eetr” is also a valid answer.
Example 2: Input: “cccaaa” Output: “cccaaa”
Explanation: Both ‘c’ and ‘a’ appear three times, so “aaaccc” is also a valid answer. Note that “cacaca” is incorrect, as the same characters must be together.
Example 3: Input: “Aabb” Output: “bbAa”
Explanation: “bbaA” is also a valid answer, but “Aabb” is incorrect. Note that ‘A’ and ‘a’ are treated as two different characters.
有题目知,本题目的是按照字符串出现次数多少进行排序并返回新的数组。其中次数相同的字符次序不作要求,大小写算不同的字符处理。本题乍一看很简单,对字符串进行遍历计数似乎就解决了,但是仔细一想,字符和其出现次数的对应关系该用什么数据结构进行记录呢,特别是要对次数进行排序,排序之后二者关系又该如何对应。这都是我们要考虑的问题。
首先可能会想到使用map来保存字符和其出现次数的对应关系,然后再用一个数组(其索引是出现次数而值是相应的字符或者字符串(如果多个字符出现次数相同))来排序,在之后反向遍历该数组生成最终的字符串。代码入下,击败了33%的用户:
想想该怎么改进呢,我们之前的题目中也经常使用数组(索引是次数、字符等信息)来代替map保存我们想要的信息,所以这里也可以使用这种方法进行改进,这种方法击败了93%的用户,代码入下。
此外,我还看到一种使用map保存排序信息的方法,这种方法思想和上面两种方法是一样的,击败了78%的用户,代码入下:
Example 1: Input: “tree” Output: “eert”
Explanation: ‘e’ appears twice while ‘r’ and ‘t’ both appear once. So ‘e’ must appear before both ‘r’ and ‘t’. Therefore “eetr” is also a valid answer.
Example 2: Input: “cccaaa” Output: “cccaaa”
Explanation: Both ‘c’ and ‘a’ appear three times, so “aaaccc” is also a valid answer. Note that “cacaca” is incorrect, as the same characters must be together.
Example 3: Input: “Aabb” Output: “bbAa”
Explanation: “bbaA” is also a valid answer, but “Aabb” is incorrect. Note that ‘A’ and ‘a’ are treated as two different characters.
有题目知,本题目的是按照字符串出现次数多少进行排序并返回新的数组。其中次数相同的字符次序不作要求,大小写算不同的字符处理。本题乍一看很简单,对字符串进行遍历计数似乎就解决了,但是仔细一想,字符和其出现次数的对应关系该用什么数据结构进行记录呢,特别是要对次数进行排序,排序之后二者关系又该如何对应。这都是我们要考虑的问题。
首先可能会想到使用map来保存字符和其出现次数的对应关系,然后再用一个数组(其索引是出现次数而值是相应的字符或者字符串(如果多个字符出现次数相同))来排序,在之后反向遍历该数组生成最终的字符串。代码入下,击败了33%的用户:
public String frequencySort(String s) { if (s == null) { return null; } Map<Character, Integer> map = new HashMap(); char[] charArray = s.toCharArray(); int max = 0; for (Character c : charArray) { if (!map.containsKey(c)) { map.put(c, 0); } map.put(c, map.get(c) + 1); max = Math.max(max, map.get(c)); } List<Character>[] array = buildArray(map, max); return buildString(array); } private List<Character>[] buildArray(Map<Character, Integer> map, int maxCount) { List<Character>[] array = new List[maxCount + 1]; for (Character c : map.keySet()) { int count = map.get(c); if (array[count] == null) { array[count] = new ArrayList(); } array[count].add(c); } return array; } private String buildString(List<Character>[] array) { StringBuilder sb = new StringBuilder(); for (int i = array.length - 1; i > 0; i--) { List<Character> list = array[i]; if (list != null) { for (Character c : list) { for (int j = 0; j < i; j++) { sb.append(c); } } } } return sb.toString(); }
想想该怎么改进呢,我们之前的题目中也经常使用数组(索引是次数、字符等信息)来代替map保存我们想要的信息,所以这里也可以使用这种方法进行改进,这种方法击败了93%的用户,代码入下。
public String frequencySort1(String s){ if(s.length()<3) return s; int [] map = new int [256]; int max = 0; for(Character c:s.toCharArray()){ map[c] ++; max = Math.max(max, map[c]); } String[] buckets = new String[max + 1]; for(int i=0; i<256; i++){ String str = buckets[map[i]]; if(map[i] > 0) buckets[map[i]] = (str == null)? "" + (char)i : (str + (char)i); } StringBuilder strb = new StringBuilder(); for(int i=max; i>=0; i--){ if(buckets[i] != null) for(char c:buckets[i].toCharArray()) for(int j=0; j<i; j++) strb.append(c); } return strb.toString(); }
此外,我还看到一种使用map保存排序信息的方法,这种方法思想和上面两种方法是一样的,击败了78%的用户,代码入下:
public String frequencySort2(String s) { char[] arr = s.toCharArray(); // bucket sort int[] count = new int[256]; for(char c : arr) count[c]++; // count values and their corresponding letters Map<Integer, List<Character>> map = new HashMap<>(); for(int i = 0; i < 256; i++){ if(count[i] == 0) continue; int cnt = count[i]; if(!map.containsKey(cnt)){ map.put(cnt, new ArrayList<Character>()); } map.get(cnt).add((char)i); } // loop throught possible count values StringBuilder sb = new StringBuilder(); for(int cnt = arr.length; cnt > 0; cnt--){ if(!map.containsKey(cnt)) continue; List<Character> list = map.get(cnt); for(Character c: list){ for(int i = 0; i < cnt; i++){ sb.append(c); } } } return sb.toString(); }
相关文章推荐
- [LeetCode]题解(python):128-Longest Consecutive Sequence
- Leetcode题解 350. Intersection of Two Arrays II
- Leetcode题解 88. Merge Sorted Array(todo)
- LeetCode 464 Can I Win 题解
- LeetCode 题解 169. Majority Element(查找多数元素)
- LeetCode题解:Binary Tree Paths
- leetcode题解-13. Roman to Integer && 14. Longest Common Prefix && 20. Valid Parentheses
- LEETCODE 7 Reverse Integer (JAVA题解)
- LEETCODE 9 Palindrome Number (JAVA题解)
- leetcode Flatten Binary Tree to Linked List C++题解
- leetcode题解-126. Word Ladder II
- LeetCode 392. Is Subsequence 题解——Java
- LeetCode题解——3Sum
- leetcode题解-203. Remove Linked List Elements
- Leetcode题解(25)
- LeetCode 238. Product of Array Except Self 题解(C++)
- leetcode题解Java | 310. Minimum Height Trees
- leetcode题解-21. Merge Two Sorted Lists
- Leetcode题解-62. Unique Paths & 63. Unique Paths II
- LeetCode题解:Path Sum