3.力扣刷题之数组中数字出现的次数

简介: 3.力扣刷题之数组中数字出现的次数

题目:剑指 Offer 56 - I. 数组中数字出现的次数


image.png

思路


解决此题首先要清楚异或的概念。相同的数异或为0,不同的数异或为1,,此外0和任何数异或等于这个数本身。

所以,本题数组里面所有数的异或=目标两个数异或。由于这两个数不同,所以异或结果必然不等于0.根据这个特性,我们可以采用分组的方法解决这个问题,且分组要满足两个条件:1.两个相同的数必须在同一组;2.两个只出现一次的数必须分配在不同组。这样我们对这两组进行异或,就可以得到两个只出现一次的数。这里拿示例1举例子:[4,1,4,6]:全部异或结果就等于1和6的异或结果。就是0001和0110异或结果是0111。0111这个二进制中1暗含什么意思?不难知道,二进制位是1,就表示1和6这个二进制位上的数不同。所以,这就是划分两个数到不同组的依据。因为0111有三个二进制位都是1,分别是第一位,第二位和第三位。这就表示了1和6的二进制数在第一、二、三位上的数是不同的。我们假设就以第一个二进制位为划分标准。当数组中的数的第一个二进制位是1的就分为第一组。数组中的数第一个二进制位是0的就划分为第二组。这样就成功的将1和6分到了不同的组别中,而相同的数例如4,因为4和4的第一个二进制位是必然相等的,这样也就实现了将两个相同的数划分到同一组。最后只需要分别将这两个组进行异或,就可以得到我们要求的答案。

解题


class Solution {
    public int[] singleNumbers(int[] nums) {
        int ret = 0;
        for(int num:nums){
            ret ^= num;//ret最终答案就是那两个只出现一次的的数异或的结果
        }
        //找到ret二进制数中第几位是1
        int target = 1;//初始位0001
        while((target & ret)==0){//如果target第一个二进制位不为1,就将target左移一位位0010,然后与相与,判断ret第二位是否为一.按此循环,知道找到ret的第一个为1的二进制位
            target = target<<1;
        }
        int a = 0, b = 0;
        for(int num:nums){
            if((num & target)==0){//第一组
                a ^= num;
            }else{//第二组
                b ^= num;
            }
        }
        return new int[]{a,b};
    }
}
相关文章
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
1月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
38 0
|
3月前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
3月前
|
存储 Java API
LeetCode------合并两个有序数组(4)【数组】
这篇文章介绍了LeetCode上的"合并两个有序数组"问题,并提供了三种解法:第一种是使用Java的Arrays.sort()方法直接对合并后的数组进行排序;第二种是使用辅助数组和双指针技术进行合并;第三种则是从后向前的双指针方法,避免了使用额外的辅助数组。
LeetCode------合并两个有序数组(4)【数组】
LeetCode------找到所有数组中消失的数字(6)【数组】
这篇文章介绍了LeetCode上的"找到所有数组中消失的数字"问题,提供了一种解法,通过两次遍历来找出所有未在数组中出现的数字:第一次遍历将数组中的每个数字对应位置的值增加数组长度,第二次遍历找出所有未被增加的数字,即缺失的数字。
|
3月前
|
前端开发
LeetCode------移动零(5)【数组】
这篇文章介绍了LeetCode上的"移动零"问题,提出了一种使用双指针的原地操作解法,该方法首先将非零元素移动到数组前端并保持相对顺序,然后填充后续位置为零,以达到题目要求。
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
19 1
|
2月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
1月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
20 4
|
1月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
19 0
Leetcode第三十三题(搜索旋转排序数组)