【java数据结构】HashMapOJ练习题
【java数据结构】HashMapOJ练习题
- 一、只出现一次的数字
- 二 、随机链表的复制
- 三 、宝石与石头
- 四、坏键盘打字
- 五、前K个高频单词
博客最后附有整篇博客的全部代码!!!
一、只出现一次的数字
只出现一次的数字
思路:
- 先遍历一遍数组,将所有元素全部存到HashMap集合中
- 再遍历一遍数组,获取每个值对应的values值,判断是否等于1
代码:
public int singleNumber(int[] nums) {
HashMap<Integer,Integer> hashMap=new HashMap<>();
for(int i=0;i<nums.length;i++){
if(hashMap.containsKey(nums[i])){
hashMap.put(nums[i],hashMap.get(nums[i])+1);
}else{
hashMap.put(nums[i],1);
}
}
for(int i=0;i<nums.length;i++){
if(hashMap.containsKey(nums[i])){
if(hashMap.get(nums[i])==1){
return nums[i];
}
}
}
return -1;
}
二 、随机链表的复制
随机链表的复制
思路:
- 定义HashMap来存储新老节点的映射关系
- 再遍历一遍,然后通过老节点的map.get().next和map.get().random获得新节点的next和random,最后再通过老节点的map.get(cur.next)和map.get(cur.random)映射出应赋值给新节点的next和random的值
map.get(cur).next = map.get(cur.next);
map.get(cur).random =map.get(cur.random);
代码:
public Node copyRandomList(Node head) {
Node cur = head;
HashMap<Node, Node> map = new HashMap<>();
while (cur != null) {
Node newNode = new Node(cur.val);
map.put(cur,newNode);
cur = cur.next;
}
cur=head;
while (cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur=cur.next;
}
return map.get(head);
}
三 、宝石与石头
宝石与石头
思路:
- 现将字符串转化为字符数组
- 将石头的每个字符存储进HashMap中,然后遍历宝石,如果HashMap中存在宝石,通过map.get()获取values值,进行count++;最后返回count。
代码:
public int numJewelsInStones(String jewels, String stones) {
char[] jewelChars = jewels.toCharArray();//宝石
char[] stonesChars = stones.toCharArray();//石头
int count = 0;
HashMap<Character,Integer> map=new HashMap<>();
for(int i = 0; i < stonesChars.length; i++){
if(map.containsKey(stonesChars[i])){
map.put(stonesChars[i],map.get(stonesChars[i])+1);
}else{
map.put(stonesChars[i],1);
}
}
for(int i = 0; i<jewelChars.length; i++){
if(map.containsKey(jewelChars[i])){
count+=map.get(jewelChars[i]);
}
}
return count;
}
四、坏键盘打字
坏键盘打字
思路:
- 将所有的字符串全部进行大写转化
- 将输出的字存储进HashMap的map1集合中
- 遍历打印的字,并且只要求输出一遍我们将出现过的字符可以重新放到一个HashMap的map2集合中,判断map1和map2两个如果都不包含则进行打印。
代码:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1= sc.nextLine();
String str2=sc.nextLine();
faultyKeyboard(str1,str2);
}
public static void faultyKeyboard(String str1,String str2){
String str3=str1.toUpperCase();
String str4=str2.toUpperCase();
char[] str5=str3.toCharArray();
char[] str6=str4.toCharArray();
HashMap<Character,Integer> map1=new HashMap<>();
HashMap<Character,Integer> map2=new HashMap<>();
for (int i = 0; i < str6.length; i++) {
if(map1.containsKey(str6[i])){
map1.put(str6[i],map1.get(str6[i])+1);
}else{
map1.put(str6[i],1);
}
}
for(int i=0;i<str5.length;i++){
if(!map1.containsKey(str5[i])&&!map2.containsKey(str5[i])){
map2.put(str5[i],1);
System.out.print(str5[i]);
}
}
}
五、前K个高频单词
前K个高频单词
思路:
- 将每个单词存储进HashMap的map集合
- 建立小根堆(在未建立好K大小的小根堆的时候,这个时候如果遇到频率相同的单词,需要j建立成大根堆)
- 遍历map,先建立好k个大小的小跟堆,堆顶元素小于入堆元素,则插入入堆元素;堆顶元素等于入堆元素,则判断单词大小,小的入堆
代码:
public List<String> topKFrequent(String[] words, int k) {
HashMap<String, Integer> map = new HashMap<>();
for (String word : words) {
map.put(word, map.getOrDefault(word, 0) + 1);
}
//2. 建立小根堆
PriorityQueue<Map.Entry<String,Integer>> minHeap = new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if(o1.getValue().compareTo(o2.getValue()) == 0) {
return o2.getKey().compareTo(o1.getKey());
}
return o1.getValue().compareTo(o2.getValue());
}
});
//3.遍历map
for(Map.Entry<String,Integer> entry : map.entrySet()) {
if(minHeap.size() < k) {
minHeap.offer(entry);
}else {
Map.Entry<String,Integer> top = minHeap.peek();
if(top.getValue().compareTo(entry.getValue()) < 0) {
minHeap.poll();
minHeap.offer(entry);
}else if(top.getValue().compareTo(entry.getValue()) == 0) {
if(top.getKey().compareTo(entry.getKey()) > 0) {
minHeap.poll();
minHeap.offer(entry);
}
}
}
}
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < k; i++) {
Map.Entry<String,Integer> tmp = minHeap.poll();
list.add(tmp.getKey());
}
Collections.reverse(list);
return list;
}
此篇博客的全部代码!!!