面试OR笔试22——数组中只出现一次的数字

本文介绍了一种高效算法,用于从整数数组中找出仅出现一次的两个数字,要求时间复杂度为O(n),空间复杂度为O(1)。通过使用异或运算将数组分为两个子数组,每个子数组含有一个唯一的数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 题目及要求

1.1 题目描述

一个整数数组中除了两个数字只出现一次之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)

例如输入数组{2, 4, 3, 6, 3, 2,5, 5}只有46只出现了一次,其他的都出现了两次,所以输出是46

 

 

2 解答

2.1 题目分析

只有一个数字只出现一次时,用异或运算的性质:任何数和本身的异或得0。也就是说从头到尾依次异或数组中的每个数字,那么最终的结果刚好是那个只出现一次的数字,因为那些成对出现两次的数字全部在异或中抵消了。

因此对于两个出现一次的数字,我们试着把原数组分成两个子数组,使得每个数组只包含一个只出现一次的数字,而其他的数字都是成对地出现两次。

首先,我们还是从头到尾依次异或数组中的每个数字,那么最终结果就是两个只出现一次的数字的异或的结果。因为其他数字都出现了两次,在异或中全部抵消了。由于这两个数字肯定不一样,那么异或的结果肯定不是0,也就是说起二进制表示中至少有一位是1。我们在结果中找到某一位为1的位置(代码实现的是最低位的1),记为第bit位。然后我们以第bit位是不是1把原数组的数字分成两组,第一组中的数字的bit位都为1,第二组的为0。那么两个相同的数字一定被分到同一组中,而两个只出现一次的数字一定被分到不同的组中。这样每个子数组都只有一个数字只出现一次,其他的都出现两次。

 

2.2 代码

#include <iostream>
using namespace std;

unsigned findFirstBit1(int n){
	unsigned bit = 0;
	for(bit=1;bit<sizeof(int)<<3 && !(n&1<<bit);++bit);
	return bit;
}

void findTwoNumbersAppearOnce(int *v, int n, int *num){
	if(!v || !num || n<2) return;
	int resXor = 0;
	for(int k1(0);k1<n;++k1) resXor ^= v[k1];
	int difBit = 1<<findFirstBit1(resXor);
	// int difBit = rexXor & (~resXor+1);	// 该句和更加简洁
	num[0] = num[1] = 0;
	for(int k1(0);k1<n;++k1)
		if(v[k1]&difBit) num[0] ^= v[k1];
		else num[1] ^= v[k1];
}

int main(){
	int v[] = {2,4,3,6,3,2,5,5};
	int res[2];
	findTwoNumbersAppearOnce(v,8,res);
	cout << res[0] << ' ' << res[1] << endl;
    return 0;
}




### 关于华为实习机考的内容与准备方法 #### 一、华为校园招聘的研发类岗位面试流程概述 华为校园招聘中的研发类岗位通常会经历多个环节,其中包括简历筛选、在线笔试(即机考)、技术面试以及综合评估等阶段。对于芯片与器件设计工程师这一方向下的数字芯片开发岗而言,其对应的机考形式主要考察应聘者的专业知识水平和技术能力[^1]。 #### 二、具体针对数字IC设计方向的机考类型及其合格标准说明 根据已公开的信息显示,在参加此类考试之前需明确知道它属于哪种类型的考核方式——比如可能是单选或多选题目加上少量编程实践;或者是全真模拟项目操作环境来检测实际动手解决问题的能力等等。而达到通过分数线则意味着考生不仅要在理论知识方面表现出色,还需要具备一定的实战经验才能顺利通关此轮选拔过程。 #### 三、关于机考覆盖的知识领域分析 该部分重点涉及但不限于以下几个方面的知识点: - **计算机组成原理**:理解处理器架构工作原理等相关概念; - **操作系统基础**:进程管理调度机制等内容也是常考点之一; - **数据结构与算法应用技巧**:像快速排序实现细节或者动态规划求解背包问题这类经典案例都可能被纳入考量范畴之内; - 此外还有Verilog HDL/VHDL硬件描述语言编写技能测试等方面的要求也值得注意。 #### 四、备考建议及相关资源推荐 为了更好地应对即将到来的大规模校招活动期间所面临的挑战,可以采取如下措施来进行充分准备工作: ##### (1)熟悉历年真题并总结规律特点 通过对过往几年内出现频率较高的某些特定类型试题的研究发现其中存在的模式特征之后加以针对性练习巩固薄弱之处即可有效提升成绩表现[^4]。 ##### (2)强化基础知识体系构建 利用课余时间复习整理大学期间学到过的各类课程教材资料,并结合实际情况适当补充扩展阅读材料以拓宽视野范围从而增强整体竞争力水平[^3]。 ##### (3)积极参与线上刷题平台训练营计划 例如牛客网提供了专门面向求职者群体开设的各种专项技能提升班次可供选择报名参与学习交流互动共同进步成长成为更优秀的自己。 ```python def sliding_window_algorithm(nums, target): start = end = total = count = min_length = 0 while end < len(nums): # 扩展窗口右边界直到满足条件为止 total += nums[end] while total >= target: current_len = end - start + 1 if not min_length or current_len < min_length: min_length = current_len # 收缩左边界寻找最优解方案 total -= nums[start] start += 1 end += 1 return min_length if min_length != float('inf') else 0 ``` 上述代码片段展示了一个典型的滑动窗口算法实例,可用于解决连续子数组最小长度等问题。掌握类似的高效算法有助于提高在机试中的答题效率和准确性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值