自学内容网 自学内容网

Map和Set相关的oj习题

1. 只出现一次的数字

136. 只出现一次的数字 - 力扣(LeetCode)

解题思路:判断当前元素是否存在于集合中,如果已经存在,则删除集合中相同的元素,如果不存在,则将该元素添加到集合中。

    public int singleNumber(int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0;i < nums.length;i++) {
            if(map.containsKey(nums[i])) {
               map.remove(nums[i]);
            }else {
                map.put(nums[i],1);
            }
        }
        for(int i = 0;i < nums.length;i++) {
            if(map.containsKey(nums[i])) {
                return nums[i];
            }
        }
        return -1;
    }

2. 复制带随机指针的链表

138. 随机链表的复制 - 力扣(LeetCode)

解题思路:要注意的是对链表深拷贝,即不能直接将节点的赋给复制链表,这样不能满足复制链表中的指针都不应指向原链表中的节点。可以通过Map.Entry将原链表的节点放入key,将新链表的节点放入value。通过getkey()和getvalue()方法设置新链表的next和random

    public Node copyRandomList(Node head) {
        Map<Node,Node> map = new HashMap<>();
        Node cur = head;
        //1.现将现将原链表的节点放入map中,再将原链表的值拷贝到新链表当中放入map中
        //使原链表和新链表对应的节点形成key-value型的键值对映射关系
        while(cur != null) {
            Node node = new Node(cur.val);
            map.put(cur,node);
            cur = cur.next;
        }
        cur = head;
        //2.再将原节点的next和random通过映射的关系,拷贝到新的节点上
        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);
    }

3. 宝石与石头

771. 宝石与石头 - 力扣(LeetCode)

解题思路:将拥有的宝石字符串按字符的形式放入HashSet,key存放字符。然后再将拥有的石头字符串按字符的形式,通过contains()方法查找,如果为true则count++。

    public int numJewelsInStones(String jewels, String stones) {
        Set<Character> set = new HashSet<>();
        for(int i = 0;i < jewels.length();i++) {
            char ch = jewels.charAt(i);
            set.add(ch);
        }
        int count = 0;
        for(int i = 0;i < stones.length();i++) {
            char ch = stones.charAt(i);
            if(set.contains(ch)) {
                count++;
            }
        }
        return count;
    }

4. 坏键盘打字

旧键盘 (20)__牛客网

解题思路:通过示例1可知,输入的小写字母被转化为了大写字母,所有我们可以在代码的开头就将字符串中的字符转化为大写。为了让坏了的键输出,可以将原始输出数据放入HashSet,然后再用实际输出的字符串以字符的形式判断HashSet中是否存在,如果存在,则删除。

import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;
 
 
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String str1 = in.nextLine();
            String str2 = in.nextLine();
            getError(str1,str2);
        }
    }
    private static void getError(String str1,String str2) {
        str1 = str1.toUpperCase();
        str2 = str2.toUpperCase();
        Set<Character> actSet = new HashSet<>();
        for(int i = 0;i < str2.length();i++) {
            char ch = str2.charAt(i);
            actSet.add(ch);
        }
        Set<Character> setBroke = new HashSet<>();
        for(int i = 0;i < str1.length();i++) {
            char ch = str1.charAt(i);
            if(!actSet.contains(ch)&&!setBroke.contains(ch)) {
                setBroke.add(ch);
                System.out.print(ch);
            }
        }
    }
}

5. 前K个高频单词

692. 前K个高频单词 - 力扣(LeetCode)

解题思路

1. 统计每个单词出现的次数,即将单词放入HashMap中,key存放单词,value存放单词出现的次数。

2. 创建一个堆,如果出现单词频率相同时,按大根堆排序,否则按照小跟堆排序,这是为了后面逆置时,打印出来的是从大到小的顺序。

3. 现将前k个Entry放入堆中,然后再将第k+1个节点依次与栈顶元素比较,如果比较的Entry的value值大于栈顶元素,则删除栈顶元素,再插入该元素,如果出现频率相同,当前Entry的key大于栈顶元素的key,则删除栈顶元素,再插入该元素。

4. 将堆元素放入链表,最后逆置返回链表即可

class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        HashMap<String,Integer> hashMap = new HashMap<>();
        //1.统计每个单词的个数
        for(String word : words) {
            if(hashMap.containsKey(word)){
                int val = hashMap.get(word);
                hashMap.put(word,val+1);
            }else {
                hashMap.put(word,1);
            }
        }
        //2.创建小跟堆,存放key-value键值对
        PriorityQueue<Map.Entry<String,Integer>> minHeap;
        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.遍历
        for(Map.Entry<String,Integer> entry : hashMap.entrySet()) {
            if(minHeap.size() < k) {
                minHeap.add(entry);
            }else {
                Map.Entry<String,Integer> top = minHeap.peek();
                if(top.getValue() < entry.getValue()) {
                    minHeap.poll();
                    minHeap.add(entry);
                }else if(top.getValue().equals(entry.getValue())) {
                    if(top.getKey().compareTo(entry.getKey()) > 0) {
                        minHeap.poll();
                        minHeap.add(entry);
                    }
                }
            }
        }
        //4.放入链表,逆置
        ArrayList<String> arrayList = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            Map.Entry<String,Integer> tmp = minHeap.poll();
            arrayList.add(tmp.getKey());
        }
        Collections.reverse(arrayList);
        return arrayList;
    }
}

原文地址:https://blog.csdn.net/2301_76515294/article/details/143725566

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!