451. Sort Characters By Frequency
Given a string, sort it in decreasing order based on the frequency of characters.
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.
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.
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.
这道题目,开始想到的是用计数排序的思想,只是用hashmap代替数组的方式,排完序后对hashmap中的value按照逆序排序,最后根据value的大小打印value次数,从而实现。最后发现超时了,等会儿继续试试其他的方案。以下是超时的方案。
class Solution {
public String frequencySort(String s) {
char []ch = s.toCharArray();
HashMap<Character,Integer> m = new HashMap();
for(int i = 0; i<s.length(); i++)
if(m.get(ch[i]) == null)
m.put(ch[i],1);
else
m.put(ch[i],m.get(ch[i])+1);
List<Map.Entry<Character, Integer>> list = new ArrayList<>(m.entrySet());
String t = "";
//降序排序
Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
for (Map.Entry<Character, Integer> mapping : list) {
int x = mapping.getValue();
while(x>0){
t+=String.valueOf(mapping.getKey());
x--;
}
}
return t;
}
}
在上一道问题还没有解决的情况下,又出现了一道新的查找表问题,也是超时!!!!问题如下 (median):
- 4Sum II
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.
To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.
Example:
Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
Output:
2
Explanation:
The two tuples are:
(0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
(1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
想法:
O
(
n
2
)
O(n^2)
O(n2)的时间复杂度,对A,B两个数组进行求和并把结果存在HashMap中,键存A[i]+B[i]的结果,值存结果出现的频率,相当于一个freq[A[i]+B[i]]++,然后对C,D也是执行同样的过程,最后,对两个HashMap 中的键进行相加,如果为0,就对值进行相乘,得到组合数,最后加到结果中。
代码如下:
class Solution {
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
/**
这道题的解题思路是,把A+B的和放在一个查找表中,C+D的和放入另一个查找表中,
两个表的和相加等于0,记录数+1时间复杂度为O(N^2)
**/
HashMap<Integer,Integer> map1 = new HashMap();
HashMap<Integer,Integer> map2 = new HashMap();
for(int i = 0; i<A.length; i++)
for(int j = 0; j<B.length; j++)
if(map1.get(A[i]+B[j])==null)
map1.put(A[i]+B[j],1);
else
map1.put(A[i]+B[j],map1.get(A[i]+B[j])+1);
int res = 0; //计数器
for(int i = 0; i<C.length; i++)
for(int j = 0; j<D.length; j++)
if(map2.get(C[i]+D[j])==null)
map2.put(C[i]+D[j],1);
else
map2.put(C[i]+D[j],map2.get(C[i]+D[j])+1);
for(int key1:map1.keySet()){
for(int key2:map2.keySet()){
if(key1 + key2 == 0)
res+=map1.get(key1)*map2.get(key2); //这里相乘是求得所有的组合
}
}
return res;
}
}
很遗憾,还是超时了,这里是 3 ∗ O ( n 2 ) 3*O(n^2) 3∗O(n2)的时间复杂度,但还是有问题。下面是经过一轮的改进,这里的改进成了 2 ∗ O ( n 2 ) 2*O(n^2) 2∗O(n2),结果AC了:
class Solution {
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
/**
这道题的解题思路是,把A+B的和放在一个查找表中,判断C,D之和的相反数是否在HashMap中,
在的话就加上频率,时间复杂度为O(N^2)
**/
HashMap<Integer,Integer> map = new HashMap();
for(int i = 0; i<A.length; i++)
for(int j = 0; j<B.length; j++)
if(map.get(A[i]+B[j])==null)
map.put(A[i]+B[j],1);
else
map.put(A[i]+B[j],map.get(A[i]+B[j])+1);
int res = 0; //计数器
for(int i = 0; i<C.length; i++)
for(int j = 0; j<D.length; j++)
if(map.get(0-C[i]-D[j])!=null)
res += map.get(0-C[i]-D[j]);
return res;
}
}
等了好久,超时三连了!!!!
下面介绍一下这位让我超时的老兄:
49. Group Anagrams
Given an array of strings, group anagrams together.
Example:
Input: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Output:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
Note:
All inputs will be in lowercase.
The order of your output does not matter.
又虎又皮的我,直接上计数排序的那套,结果发现又是超时!!!!心态有点炸了
class Solution {
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String> >res = new ArrayList();
for(int i = 0; i<strs.length; i++){
if(strs[i] == null) // 剪枝
continue;
List<String>L = new ArrayList();
int []freq1 = new int[26];
tofreq(strs[i],freq1);
L.add(strs[i]);
for(int k = i+1; k<strs.length;k++){
if(strs[k] == null) // 剪枝的时候别忘了这里,否则出bug
continue;
int []freq2 = new int[26];
tofreq(strs[k],freq2);
if(issame(freq1,freq2)){
L.add(strs[k]);
strs[k] = null; // 剪枝操作,下次到str[k]直接跳过
}
}
res.add(L);
}
return res;
}
public boolean issame(int []a, int []b){
for(int i = 0; i<26; i++)
if(a[i] != b[i])
return false;
return true;
}
public void tofreq(String str, int []freq){
char []x = str.toCharArray();
for(int i=0; i<str.length(); i++)
freq[x[i]-'a']++;
}
}