1、给定一个字符串,要求字母按照频率由高到低打印,要求时间复杂度为O(N)。
首先是复杂度不为O(N)的:
public static String frequencySort(String s) {
Map<Character, Integer> map = new HashMap<>();
if (s.length() > 0) {
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
map.put(s.charAt(i), map.get(s.charAt(i)) + 1);
} else {
map.put(s.charAt(i), 1);
}
}
} else {
return null;
}
Set<Map.Entry<Character, Integer>> entries = map.entrySet();
List<Map.Entry<Character, Integer>> collect = entries.stream()
.sorted(((o1, o2) -> o2.getValue() - o1.getValue()))
.collect(Collectors.toList());
StringBuffer stringBuffer = new StringBuffer();
for (Map.Entry<Character, Integer> m : collect) {
for (int i = 0; i < m.getValue(); i++) {
stringBuffer.append(m.getKey());
}
}
return stringBuffer.toString();
}
经过改进时间复杂度为O(N):
思路:map集合存放字母和出现频率;entry集合存放字母和累计的String;最后两个集合共用一个key,将map集合排序,用map集合的key对应entry集合的key;就能得到出现频率从高到低的字母String,用StringBuffer 合并即可。
public static String frequencySort1(String s) {
Map<Character, Integer> map = new HashMap<>();
Map<Character,String> entry =new HashMap<>();
if (s.length() > 0) {
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
map.put(s.charAt(i), map.get(s.charAt(i)) + 1);
entry.put(s.charAt(i),entry.get(s.charAt(i))+s.charAt(i));
} else {
entry.put(s.charAt(i),String.valueOf(s.charAt(i)));
map.put(s.charAt(i), 1);
}
}
} else {
return null;
}
List<Map.Entry<Character, Integer>> collect = map.entrySet()
.stream()
.sorted(((o1, o2) -> o2.getValue() - o1.getValue()))
.collect(Collectors.toList());
StringBuffer stringBuffer = new StringBuffer();
for (Map.Entry<Character, Integer> m : collect) {
stringBuffer.append(entry.get(m.getKey()));
}
return stringBuffer.toString();
}
2、给定一个n*m的矩阵,求从左上角到右下角的路径的和的最小值(每次只能往右或者往下走)
思路:动态规划解决,对于第一行和第一列而言,每个位置到原点最近距离就是当前位置的到原点的和(直线走),其他的位置的最小值则是 当前位置值和左边 与 当前值和上边的最小值即可。
public static int uniquePaths(int[][] arr) {
// write code here
int sum = arr[0][0];
for(int i=1;i<arr.length;i++){
arr[i][0]+=arr[i-1][0];
}
for(int i=1;i<arr[0].length;i++){
arr[0][i]+=arr[0][i-1];
}
for(int i=1;i<arr.length;i++)
for (int j=1;j<arr[0].length;j++){
arr[i][j]=Math.min( arr[i][j]+arr[i][j-1],arr[i][j]+arr[i-1][j]);
}
return arr[arr.length-1][arr[0].length-1];
}