给定一个字符串数组,再给定整数k,请返回出现次数前k名的字符串和对应的次数。 返回的答案应该按字符串出现频率由高到低排序。如果不同的字符串有相同出现频率,按字典序排序。 对于两个字符串,大小关系取决于两个字符串从左到右第一个不同字符的 ASCII 值的大小关系。 比如"ah1x"小于"ahb","231"<”32“ 字符仅包含数字和字母 输入: ["a","b","c","b"],2 返回值: [["b","2"],["a","1"]] 说明: "b"出现了2次,记["b","2"],"a"与"c"各出现1次,但是a字典序在c前面,记["a","1"],最后返回[["b","2"],["a","1"]]
这个题目也是面试比较常见的题目,网上很多算法,利用Stream应该是最简洁的。但是都不利于初学者的理解,本算法使用都是JAVA基础知识,实现比较简单,缺点是会比较消耗资源。
public class ArrayTest {
public static void main(String[] args) {
String[] arr = {"abcd","abcd","abcd","pwb2","abcd","pwb2","p12","p944"};
test(arr, 3);
}
/**
* 这个解法应该是初学者最能够理解的吧,全是基础知识,虽然比较消耗资源
* @param arr
* @param k
* @return
*/
public static List test(String[] arr, Integer k) {
// 排重计算
Map<String, Integer> map = new HashMap<>(16);
for (String key : arr) {
Integer value = map.get(key);
if (value == null) {
map.put(key, 1);
} else {
value++;
map.put(key, value);
}
}
//将map转成java对象
List<Node> nodeList = new ArrayList<>();
Set<String> keySet = map.keySet();
for (String key : keySet) {
Node node = new Node();
node.setKey(key);
node.setValue(map.get(key));
nodeList.add(node);
}
// 进行排序
Collections.sort(nodeList);
// 取前K位的值
List<Node> nodeList1 = nodeList.subList(0, k);
// 打印数据
System.out.println(nodeList1);
return nodeList1;
}
}
class Node implements Comparable<Node> {
private String key;
private Integer value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
/**
* 按格式重写toString
* @return
*/
@Override
public String toString() {
return "[" + key + "," + value + "]";
}
/**
* 先以value排序,再以key做自然排序
* @param o
* @return
*/
@Override
public int compareTo(Node o) {
int num = o.getValue() - this.getValue();
return num == 0 ? this.getKey().compareTo(o.getKey()) : num;
}
}