重复的数:

题目描述:1到1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次,找出这个重复的值。

解法1:巧妙使用位运算


public static void main(String[] args) {
		int N = 11;
		int[] a = new int[N];
		//初始化数组   不包括最后一个元素
		for (int i = 0; i < a.length - 1; i++) {
			a[i] = i + 1;
		}
		//数组的最后一个元素是随机数  就是和前面重复的那个数k   模拟这个重复的数字出现在末尾  实际不一定   但是对于算法不影响
		a[a.length - 1] = new Random().nextInt(N - 1) + 1;
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}
		System.out.println();  //打出换行
		int x = 0;
		for (int i = 1; i < N ; i++) {

			x = (x ^ i);
		}
		for (int i = 0; i < N; i++) {

			x = x ^ a[i];
		}
		System.out.println(x);
	}
}





解析:上述算法等价于:1

解法2:使用辅助数组

public static void main(String[] args) {
		int N = 11;
		int[] a = new int[N];
		//初始化数组   不包括最后一个元素
		for (int i = 0; i < a.length - 1; i++) {
			a[i] = i + 1;
		}
		//数组的最后一个元素是随机数  就是和前面重复的那个数k   模拟这个重复的数字出现在末尾  实际不一定   但是对于算法不影响
		a[a.length - 1] = new Random().nextInt(N - 1) + 1;

		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}
		System.out.println();  //打出换行
		// 开辟一个辅助数组空间  每一个数组元素存储的是  原来数组中对应的元素出现的次数   有点像桶排序的计数器
		int[] helper=new int[N];
		for(int i=0;i<N;i++){
			helper[a[i]]++;
		}
		for(int i=0;i<N;i++){
			if(helper[i]==2){
				System.out.println(i);
				break;
			}
		}

	}
}

总结:

第一种解法的感悟 :此种解法就是要构造K,使其出现次数为奇数次,其余的数据出现次数都是偶素次,
那么连续的疑惑操作之后,偶数次出现的数据都没了,剩下的就是奇数次出现的数据K 但是局限于数据必须连续

第二种解法的感悟:以空间换时间 如果原数据中出现了很大的数据 那么就必须要构造一个很大的辅助数组 但是这种方法适合通用 不必要求数据连续性

落单的数:

题目描述:某一个数组里面只有一个数K出现了一次,其余的都出现了2次,找出这个数。

public static void main(String[] args) {
		int[] a=new int[]{1,1,2,2,3,3,4,4,5,5,6,7,7,8,8,9,9,0,0};
		int x=0;
		for(int i=0;i<a.length;i++){
			x=x^a[i];
		}
		System.out.println(x);
	}
	
	//解析:所有出现偶数次的数据  都会在连续的异或之后消掉,只剩下出现奇数次的数据