Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
1.题目描述
给你一个整数数组 nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 **三次 。**请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2]
输出:3
复制代码
示例 2:
输入:nums = [0,1,0,1,0,1,99]
输出:99
复制代码
提示:
- 1 <= nums.length <= 3 * 104
- -231 <= nums[i] <= 231 - 1
- nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
Tips: 力扣地址:leetcode-cn.com/problems/si…
2. 思路分析
方式1:整个最容易想到的方法解决就是通过额外空间,定义一个HashMap,key为元素,value为元素出现的次数。这个是实现最容易想到的解决方案,遍历整个数组然后将数组的次数统计出来到map的value中。AC代码如下代码1。
方式2:上面的方法是最简单的最容易想到的,那么有没有比较巧妙的方法。都知道int的类型是32位我们用额外创建一个int[]数组a长度为32。用长度来模拟int的位数,int[i]的值表示该位上面的1的次数。相同的数据位上的数据是相同的。然后将用a[i]%3 & 1 与是否等于1来判断。如果等于1表示这个位上的1属于只出现一次的元素。AC代码如下代码2.
3. AC代码
代码1:
class Solution {
public int singleNumber(int[] nums) {
TreeMap<Integer,Integer> data = new TreeMap<>();
Arrays.stream(nums).forEach(item-> data.put(item, data.getOrDefault(item, 0)+1));
Set<Map.Entry<Integer, Integer>> entries = data.entrySet();
for(Map.Entry<Integer, Integer> item : entries){
if( item.getValue() == 1){
return item.getKey();
}
}
return 0;
}
}
复制代码
代码2:
class Solution {
public int singleNumber(int[] nums) {
int[] cnt = new int[32];
for (int x : nums) {
for (int i = 0; i < 32; i++) {
if (((x >> i) & 1) == 1) {
cnt[i]++;
}
}
}
int ans = 0;
for (int i = 0; i < 32; i++) {
if ((cnt[i] % 3 & 1) == 1) {
ans += (1 << i);
}
}
return ans;
}
}
复制代码
4. 总结
方式1是最容易想到也最简单的,方式2就是巧妙的利用位和数组进行转换。巧妙求解
扫描二维码关注公众号,回复:
13751615 查看本文章
我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢