Map和Set练习题

1、List当中存放了10万个随机的数据,找出第一个重复的数字

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i <10_0000 ; i++) {
            int num = random.nextInt(10_0000);
            list.add(num);
        }
        HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i <10_0000 ; i++) {
            if(set.contains(list.get(i))) {
                System.out.println(list.get(i));
                return;
            }else {
                set.add(list.get(i));
            }
        }
    }

2、List当中存放了10万个随机的数据,把重复的数字全部去重

public static void main2(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i <10_0000 ; i++) {
            int num = random.nextInt(10_0000);
            list.add(num);
        }
        HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i <10_0000 ; i++) {
            set.add(list.get(i));
        }
        //遍历set
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }

3、有10万个数据,统计重复的数字及出现的次数

public static void main1(String[] args) {
        HashMap<Integer,Integer> map = new HashMap<>();
        ArrayList<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i <10_0000 ; i++) {
            int num = random.nextInt(10_0000);
            list.add(num);
        }
        //1.遍历list
        for (Integer key : list) {
            if(map.get(key) == null) {
                map.put(key,1);
            }else {
                int val = map.get(key);
                map.put(key,val+1);
            }
        }
        for(Map.Entry<Integer,Integer> entry:map.entrySet()) {
            if(entry.getValue() > 1) {
                System.out.println("重复的数字:"+entry.getKey()+"出现的次数是:"+entry.getValue());
            }
        }
    }

4、宝石与石头
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。
示例:

输入: J = "aA", S = "aAAbbbb"
输出: 3
输入: J = "z", S = "ZZ"
输出: 0
class Solution {
    public int numJewelsInStones(String J, String S) {
        HashSet<Character> setJ = new HashSet<>();
        int count = 0;
        //先把宝石放到集合当中
        char[] chJ = J.toCharArray();
        for(char ch : chJ) {
            setJ.add(ch);
        }
        //遍历石头 看集合里面有多少个宝石
        char[] chS = S.toCharArray();
        for(char chs : chS){
            if(setJ.contains(chs)) {
                count++;
            }
        }
        return count;
    }
}

力扣原题链接

5、复制带随机指针的链表

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的 深拷贝。
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

val:一个表示 Node.val 的整数。

random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。

解法:

我们用哈希表来解决这个问题
首先创建一个哈希表,再遍历原链表,遍历的同时再不断创建新节点
我们将原节点作为key,新节点作为value放入哈希表中
在这里插入图片描述
第二步我们再遍历原链表,这次我们要将新链表的next和random指针给设置上

在这里插入图片描述
从上图中我们可以发现,原节点和新节点是一一对应的关系,所以
map.get(原节点),得到的就是对应的新节点
map.get(原节点.next),得到的就是对应的新节点.next
map.get(原节点.random),得到的就是对应的新节点.random
所以,我们只需要再次遍历原链表,然后设置:
新节点.next -> map.get(原节点.next)
新节点.random -> map.get(原节点.random)
这样新链表的next和random都被串联起来了
最后,我们然后map.get(head),也就是对应的新链表的头节点,就可以解决此问题了。

class Solution {
    public Node copyRandomList(Node head) {
        Node cur = head;
        HashMap<Node,Node> map = new HashMap<>();
        while(cur != null){
            Node node = new Node(cur.val);
            map.put(cur,node);
            cur = cur.next;
        }
        //cur == null;    -> 链表已经遍历完成了 -》 新老节点的对应关系已经存在
        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);
    }
}

力扣原题链接

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值