zoukankan      html  css  js  c++  java
  • 数组中仅仅出现一次的数字

    题目

    一个整型数组里除了两个数字之外,其它数字都出现了两次。请找出这两个仅仅出现一次的数字。

    要求时间复杂度O(n),空间复杂度O(1)

    思路

    我们知道假设把题目中的两个数字换成一个的话。整个数组内的元素连续异或。终于的数便是那个出现一次的数,由于异或的性质:同样为0。不同为1。所以有不论什么数字异或自己都是0。

    换成两个数字后,我们能够继续全局异或。得到的数必定不等于0,那么也就是说二进制中必定有一位是1,比方是第K位为1,那么依照全部元素的第K位是否为1划分成两个子区间,这样,我们在这两个子区间内依照第一次的方法求解就可以。


    代码

    public static void getTwotimeNumber(int [] num)
    	{
    		if(num == null || num.length < 0)
    			return ;
    		int sum = num[0];
    		for(int i=1;i<num.length ;i++)
    			sum = sum^num[i];
    		
    		String sumBin = Integer.toBinaryString(sum);  //获取终于和的二进制
    		 
    		
    		int index = sumBin.length()-sumBin.lastIndexOf("1")-1;   //推断最后一位二进制的下标
    	//	System.out.println(index);
    		
    		int result1 = 0;
    		int result2 = 0;
    		for(int i = 0;i<num.length ;i++)
    		{
    			if(((num[i]>>index) & 1) ==1)
    				result1 ^= num[i];
    			else
    				result2 ^= num[i];
    		}
    		
    		System.out.println(result1+"...."+result2);
     
    		
    	}

    延伸

    看完这个题目。我又想到了假设数组中出现一次的数字有3个,4个,5个......,那就是怎么找出数组中不反复的数字或者是找出数组中反复的数字。


    有这么个题目:长度为N的数组,元素都是1~N,查找反复的数字

    有这么几种思路:
    1、先快排,然后推断相邻元素是否同样,时间复杂度O(nLogN)

    2、比方第 i 个位置的数字为 j 。我们将 j 交换到下标为 j 的数组上,假设某一次发现已经交换过了,那么此数反复

    3、利用Java中的BitSet。每一位为0或1,所以类似上面的,比方当找到5的时候。我们将BitSet的第5位置为true。默认是false。所以当某一次发现该位上的没设置就已经成为true。就说明肯定出现过反复




    最后推荐  一些面试题。转关注的一个博客, 上面总结的不错。
     


  • 相关阅读:
    UVA 1386 Cellular Automaton
    ZOJ 3331 Process the Tasks
    CodeForces 650B Image Preview
    CodeForces 650A Watchmen
    CodeForces 651B Beautiful Paintings
    CodeForces 651A Joysticks
    HUST 1601 Shepherd
    HUST 1602 Substring
    HUST 1600 Lucky Numbers
    POJ 3991 Seinfeld
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6877801.html
Copyright © 2011-2022 走看看