java:只出现一次的数字(看完必会)

这篇博客介绍了如何解决LeetCode中关于找出数组中唯一出现的元素的题目。首先,通过HashSet实现,利用其不允许重复的特性找到唯一元素。其次,使用按位异或的方法,根据异或的性质找出唯一元素。对于更复杂的变式,如有两个唯一元素的情况,依然使用HashSet,但需注意避免错误地移除元素。最后,面对出现次数为3的元素情况,使用HashMap记录元素出现的次数,从而找到唯一元素。
摘要由CSDN通过智能技术生成

LeetCode题目列表:

在这里插入图片描述

一,实例一

题目:
在这里插入图片描述
答案:
这道题有好几种解决方法,先看下第一种,使用HashSet, HashSet中不允许有重复的值

class Solution {
    public int singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for(int num:nums){
            //将当前元素加入到set中,set中不允许有重复的元素
            boolean flag = set.add(num) 
            //如果set中已经存在num这个元素,那么前面的添加就是失败的,返回false
            if(!flag){
                set.remove(num); //将数组中重复的元素,从set集合中移除
            }
        }
        //set集合中只剩下数组中唯一出现的元素
        return set.iterator().next(); //返回set序列中的第一个元素
    }
}

第二种方法就是按位异或,一个值和0进行按位异或操作所得为该值,相同的两个值进行异或操作,所得为0(甲 按位异或 0 得 甲,甲 按位异或 甲 得 0)。

根据这个性质,由于每个重复元素重复两次,故他们在遍历后将相互抵消,而唯一元素只出现一次,故将得到保留

class Solution {
    public int singleNumber(int[] nums){
        int singleNum = 0;
        for(int num:nums){
            //一个值和0进行按位异或操作所得为该值,相同的两个值进行异或操作,所得为0
            singleNum ^= num;
        }
        return singleNum;
    }
}

以上只是简单的程度,下面来个该题的变式,中等难度

二,实例二

题目:
在这里插入图片描述
答案:
这题不适合使用按位异或的方法,因为给出的数组中有两个数在数组中是唯一的。这里采用HashSet实现

class Solution {
    public int[] singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for(int num : nums){
            if(!set.add(num)){
                set.remove(num);
            }
        }
        int[] arr = new int[2];
        int i=0;
        for(int num : set){ //遍历set中的每一个元素
            arr[i++] = num;
        }
        return arr;
    }
}

三,实例三

题目:
在这里插入图片描述
思路:
注意该题和前面不同的是,除了唯一元素,其余元素出现的次数为3,而不是2,所以不能用HashSet。eg:{2, 2,3, 2},按照之前用HashSet的方法,第一次出现2时,将其添加到set中,当第二次出现2时时,先判断能不能添加成功,如果不行,说明set中已经存在该元素,于是把该元素删除;现在set中已经不存在2这个元素了;当第三次出现2时,又把2添加到了set中,所以set中最终存储了两个元素2和3,实际上2是不符合,所以这题不能用HashSet来实现,而是用HashMap

答案:

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        //主键存数组元素,主键对应的值为该主键出现的次数
        for(Integer num : nums){
            Integer count = map.get(num); //通过get(num),获取主键为num对应的值
            //如果不存在主键为num的值,则将count==1;如果存在,直接在原基础上+1
            count = (count==null) ? 1 : ++count; 
            map.put(num,count); //键值对存入map中
        }
        for(Integer key : map.keySet()){
            if(map.get(key) == 1){  //找到数组中只出现过一次的值
                return key;
            }
        }
        return -1;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值