LeetCode Single Number III

寻找唯一出现的两个数
本文介绍了一种在常空间复杂度下,通过位运算快速找出数组中仅出现一次的两个数的方法。

Description:

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

Solution:

这道题目的基础做法有很多,但是在线性时间,O(1)的空间解决还是有点难度的

首先不难发现,按照我们前面解决问题的方案,全部异或之后的结果是x^y,问题是如何将这两个分开

巧妙的方法是,x^y肯定不为0,那么不妨找到第一个在二进制中为1的bit,表示x和y两个数字,在这个bit上一个是1,一个是0。所以再将所有的nums按照这个bit是0还是1分为两组,各自做异或就能分别求出x和y。

找到第一个为1的bit有很多种方法,简单的一种是

sum & (~(sum - 1))

记得是Steiner Tree里面提到的用法,也可以用循环做。


<span style="font-size:18px;">public class Solution {
	public int[] singleNumber(int[] nums) {
		int n = nums.length;

		int[] ans = new int[2];

		int sum = 0;
		for (int i = 0; i < n; i++)
			sum = sum ^ nums[i];

		int highest_bit = sum & (~(sum - 1));

		for (int i = 0; i < n; i++) {
			if ((nums[i] & highest_bit) == 0)
				ans[0] ^= nums[i];
			else
				ans[1] ^= nums[i];
		}

		return ans;
	}
}</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值