一个整型有序数组,数组里除了一个数字只出现了一次之外,其他的数字都出现了两次,请写程序找出这个只出现一次的数字。

一个整型有序数组,数组里除了一个数字只出现了一次之外,其他的数字都出现了两次,请写程序找出这个只出现一次的数字。

1、运用hashMap:时间复杂度O(n)

  1. 思路
    可以使用一个Map来接收数组,Map对应的键值key就是数组中的元素,value就是这个元素出现的次数。通过遍历一次数组中的元素,如果元素出现在Map中,则将其对应的value加1,否则将元素添加到Map中,这样遍历一遍数组,我们就可以得到数组中每个元素对应出现的次数,然后再通过遍历一遍Map,返回value为1对应的key就是我们需要求得元素。
  2. 时间复杂度
    因为首先需要遍历一遍数组,时间复杂度为O(n),便利数组构建完Map后需要遍历一遍Map找到value为1的元素,而Map的个数为n/2,时间复杂度为O(n/2),所以总的时间复杂度为O(n)。
  3. 空间复杂度
    因为需要建立一个Map,而且最后Map的大小为n/2,所以空间复杂度为O(n)。
public static void findNumsAppearOnce1(int[] arr) {
	//Map对应的键值key就是数组中的元素,value就是这个元素出现的次数
	Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
	for (int i : arr) {
		if (hashMap.containsKey(i)) {
			hashMap.put(i, hashMap.get(i) + 1); //如果存在,value值加1
		} else {
			hashMap.put(i, 1); //如果不存在,存入hashMap,value值等于1
		}
	 }
	//遍历一遍map,返回value为1对应的key就是我们需要求得元素
	Set<Integer> set = hashMap.keySet();
	for (int i : set) {
		if (hashMap.get(i) == 1) {
			System.out.print(i+" ");
		}
	}
}

2、运用异或运算符:时间复杂度O(n)

  1. 思路
    异或运算的特点:任何一个数字和自己做异或运算的结果都是0,任何数字和0运算的结果都是本身。可以考虑从数组的第一个元素开始,逐个和后面的元素做异或操作,最后的计算结果就是要找的只出现一次的数。
public static void findNumAppearOnce(int[] arr) {
	int result = 0;
	for (int i = 0; i < arr.length; i++) {
		result ^= arr[i];
	}
	System.out.println(result);
}

3、运用二分查找法:时间复杂度O(log2n)

public static int method(int[] arr) {
	int start = 0; //定义变量,记录最小的索引
	int end = arr.length - 1; //定义变量,记录最大的索引
	int mid = (start + end) / 2; //定义变量,记录中间的索引
	while ((arr[mid] == arr[mid - 1]) || (arr[mid] == arr[mid + 1])) {
		if ((arr[mid] != arr[mid - 1]) && (arr[mid] != arr[mid + 1])) {//与两边的数不等,break
			break;
		} else if (arr[mid] == arr[mid + 1]) {  //中间值与右边的值相等
			if ((arr.length - 1 - mid + 1) % 2 == 0) { //加上mid对应的数后,右边字数组的数为偶数
				mid = 0 + (mid - 1) / 2;
			} else {
				mid = (mid + (arr.length - 1)) / 2;
			}
		} else {   //中间值与左边的值相等
			if ((mid + 1) % 2 == 0) { //加上mid对应的数后,左边字数组的数为偶数
				mid = ((mid + 1) + (arr.length - 1)) / 2;
			} else {
				mid = (0 + mid) / 2;
			}
		}
		//判断,到数组的两端了,也break
		if (mid == 0 || mid == arr.length - 1) {
			break;
		}
	}
	return mid;  //如果数组中有这个元素,则返回
}

参考地址:
https://www.cnblogs.com/hezhiyao/p/7539730.html
https://blog.csdn.net/yangfeisc/article/details/45314703

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值