数字在数组中出现一次的情况

1.数字在数组中出现一次的情况

(《剑指OfferP211,《编程之美》P38

1)问题描述:

一个数组中,一个或两个数字只出现了一次,其他数字都出现了两次,找到这两个数字。

2)解决思路

解法一:遍历列表,使用哈希表记录下每个数字出现的次数,每次遇见一个新的数字,则在哈希表中增加一个元素;遇见相同的数字,即该数字出现两次,则从哈希表中将该元素删除。

时间复杂度:O(n);空间复杂度:O(1)(最好情况)O(n)(最坏情况)

解法二:只有一个数字出现一次的情况,可使用数组中所有数字异或,结果即为所需的数字;

若有两个数字出现一次,则异或的结果一定不为0,该结果的二进制表示中至少有一位上为1.取该结果第一个为1的位置,即为第N位。将数组中的所有数字分为第N位为10两个不同的数组,两个数组中分别含有一个所需求的数字结果,同样分别采取异或的方法即可获得。

时间复杂度:O(n);空间复杂度:O(1)

代码实现:

    //num1,num2分别为长度为1的数组。传出参数
    //将num1[0],num2[0]设置为返回结果
    public class Solution {
        public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
            if (array == null || array.length <= 1)
                return;
            // 进行一次遍历,将所有元素异或
            int result = 0;
            for (int data : array)
                result ^= data;

            // 先找到结果值result的第一个不为0的二进制位置index
            if (result == 0) return;
            int index = 1;
            for (; (result & index) == 0; index <<= 1);

            // 再次遍历,将index位是否为1分为两个数组分别进行异或,得到的结果值即为所求
            num1[0] = 0; num2[0] = 0;

            for (int data : array) {
                // 注意比较该位是否为1
                if ((data & index) == index)
                    num1[0] ^= data;
                else
                    num2[0] ^= data;
            }
        }
    }


// (两个)数字在数组中出现一次的情况

#include "stdafx.h"
#include <iostream>
using std::cout; using std::cin;

//异或算法得到结果
//参数:data_array操作数组,length表示数组长度
int Calculate_Fun(int data_array[], int length)
{
	int result = 0;
	for (int i = 0; i < length; i++)
	{
		result ^= data_array[i];//异或过程
	}
	return result;
}

//找到结果中第一个非零值的位置n(从末位开始)
int Find_N(int result)
{
	int index = 0;
	const int SIZE_OF_BIT = 8;
	while (((result & 1) == 0) && (index < SIZE_OF_BIT * sizeof(int)))
	{
		result >>= 1;
		++ index;
	}
	return index;
}



int _tmain(int argc, _TCHAR* argv[])
{
	//输入待测试数组
	//printf("输入包含有数据的数组:");
	const int MAXSIZE = 10;
	//int data_array[MAXSIZE];
	//for (int i = 0; i < MAXSIZE; i++)
	//{
	//	cin >> data_array[i];
	//}

	//调试
	int data_array[MAXSIZE] = {1,1,2,3,3,4,5,5,6,6};

	//第一次异或遍历
	int reslut;
	reslut = Calculate_Fun(data_array,MAXSIZE);

	if (reslut == 0)
	{
		printf("数组中没有只出现一次的数组");
	}
	else
	{
		//找到结果中第一个非零值的位置n(从末位开始)
		int index = Find_N(reslut);
		//划分数组
		int judge_num = 1;
		for (int i = 0; i < index; i++)
		{
			judge_num <<= 1;
		}
		int left_data[MAXSIZE / 2], right_data[MAXSIZE / 2];
		int left_index = 0, right_index = 0;
		for (int i = 0; i < MAXSIZE; i++)
		{
			if ((data_array[i] & judge_num) == 0)
			{
				left_data[left_index] = data_array[i];
				++left_index;
			}
			else
			{
				right_data[right_index] = data_array[i];
				++right_index;
			}
		}
		printf("得到的两个只出现一次的数字分别为:%d,%d", 
			Calculate_Fun(left_data, MAXSIZE / 2),
			Calculate_Fun(right_data, MAXSIZE / 2));
	}
	return 0;
}

解法三:(适用于缺少某一个ID的情况)使用不变量法,即求取总和或者平方和,减去当前数组总和或平方和,建立方程组求解。

	a = a + b;
	b = a - b;
	a = a - b;


2.实现不用第三存储变量temp直接实现交换两个变量的值

(《深入理解计算机系统》P34)这里要注意如*x = *y的情况,因为a^a=0

 

void inplace_swap(int *x,int *y){
	*y = *x ^ *y;
	*x = *x ^ *y;
	*y = *x ^ *y;
}

实现流程:(使用了a^a=0,前面例子中也使用了该方法)

*x                        *y
a                         b
a                       a^b
a^a^b = b               a^b
b                   a^b^b=a

实现方法二:(基于加减法)

《剑指OfferP239  这里要注意相加后会不会有溢出情况

	a = a + b;
	b = a - b;
	a = a - b;

实现方法三:(适用于Java变量缓存机制)

x = y + 0 * (y = x);  // 先将y参与运算,然后将x值赋给y,最后再将结果(也就是y)赋给x 


### IntelliJ IDEA 中通义 AI 功能介绍 IntelliJ IDEA 提供了一系列强大的工具来增强开发体验,其中包括与通义 AI 相关的功能。这些功能可以帮助开发者更高效地编写代并提高生产力。 #### 安装通义插件 为了使用通义的相关特性,在 IntelliJ IDEA 中需要先安装对应的插件: 1. 打开 **Settings/Preferences** 对话框 (Ctrl+Alt+S 或 Cmd+, on macOS)。 2. 导航到 `Plugins` 页面[^1]。 3. 在 Marketplace 中搜索 "通义" 并点击安装按钮。 4. 完成安装后重启 IDE 使更改生效。 #### 配置通义服务 成功安装插件之后,还需要配置通义的服务连接信息以便正常使用其提供的各项能力: - 进入设置中的 `Tools | Qwen Coding Assistant` 菜单项[^2]。 - 填写 API Key 和其他必要的认证参数。 - 测试连接以确认配置无误。 #### 使用通义辅助编程 一旦完成上述准备工作,就可以利用通义来进行智能编支持了。具体操作如下所示: ##### 自动补全代片段 当输入部分语句时,IDE 将自动提示可能的后续逻辑,并允许一键插入完整的实现方案[^3]。 ```java // 输入 while 循环条件前半部分... while (!list.isEmpty()) { // 激活建议列表选择合适的循环体内容 } ``` ##### 解释现有代含义 选中某段复杂的表达式或函数调用,右键菜单里会有选项可以请求通义解析这段代的作用以及优化意见。 ##### 生产测试案例 对于已有的业务逻辑模块,借助于通义能够快速生成单元测试框架及初始断言集,减少手动构建的成本。 ```python def test_addition(): result = add(2, 3) assert result == 5, f"Expected 5 but got {result}" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值