給出2n+1(2n+2)個數,其中有n個數是成對出現的,找出只出現一次的一個數/兩個數

1 給出2n+1個數,其中有n個數是成對出現的,讓我找出裏面只出現了一次的那個數。
2 。給出2n+2個數,其中有n個數是成對出現的,讓我找出裏面只出現了一次的那兩個數。
對於第一個問題我們用位運算來解決中的異或運算,注意異或運算的運算法則:相同爲0,不同爲本身
在這裏插入圖片描述
代碼如下:

package yihuo;

public class yihuo {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int personal=0;
		int personal1=0;
		int a[]= {1,2,8,9,7,4,3,2,4,7,3,8,9,1,12};
		for(int i=0;i<a.length;i++) {
			personal=a[i]^personal;
		}
		System.out.println("出現了奇數次的那一個數 personal="+personal);
	}

}

運行截圖:
在這裏插入圖片描述
2 。給出2n+2個數,其中有n個數是成對出現的,讓我找出裏面只出現了一次的那兩個數。
解題思路:因爲是偶數個不同(以),所以異或運算之後得到的是兩個不同元素的異或運算值,得不到想要的。但是如果我們把這一組數據分爲兩組,每一組分擔一個不同的,分組異或運算之後,每一組就會把那個單一元素給找出來。
i.困難:在不知道的情況下,如何將N+2個數據劃分爲我們想要的兩組。
ii.解決方法:將N+2個數據異或之後,將會得到我們想要的那兩個值的異或值,得到的這個異或值,它的二進制中肯定有至少一位是1(因爲不同),這裏我們取最高位是1的那一位,將所有數據中對應位按照該位置上是0和1分開,分成兩組,然後分組異或,將會得到兩個值,就是我們想要的結果了。
如何得到異或值的二進制最高一位爲1的位置呢,我用向左移動來實現。肯定有一個1,所以最壞情況是移動到最後成10000000,跳出循環。
for(;p<127;) {//一直向左移動,找到personal1剛開始爲1的位置也就是兩個數不同的位置。 p=p<<1; youyicount++; }

每次記錄向左移動次數,然後 location=8-youyicount;來得到那個位置。
爲了在location位置上將所有數據分成兩組,我想到0&n(任何數)都爲0,1&n(n是1則1,n是0則0),所以將每個值和2的location-1次方做與運算,如果結果爲零,說明該數據的二進制在location位置上爲0,否則爲1。根據0還是1得到兩組
代碼如下:

for(int i=0,j=0,m=0;i<b.length;i++) {
			int t=b[i]&loc;
			if(t==0) {
				List1.add(b[i]);//兩個唯一的數,在第Location位置上不同,所以按照Location位置
//				                                              上0或1分爲兩組,可以將兩個唯一值分開,分開後,按照上面的方法分別求即可
			}else {
				List2.add(b[i]);
			}
		}

得到兩組後,就回到第一個問題了,想了好久,覺得可以,點贊支持一下哦

完整代碼如下:
package yihuo;

import java.util.ArrayList;

public class yihuo {
	
//	給你n個數,其中有且僅有一個數出現了奇數次,其餘的數都出現了偶數次。
//	用線性時間常數空間找出出現了奇數次的那一個數。
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int personal1=0;
		int location=0;
		int loc;
		int one=0;
		int two=0;
		int youyicount=0;
		int b[]= {1,2,8,9,7,4,2,4,7,3,8,1,12,10,12,10,28,20,28,20};
		ArrayList List1 = new ArrayList(); 
		ArrayList List2 = new ArrayList(); 
		for(int i=0;i<b.length;i++) {
			personal1=b[i]^personal1;
		}
		System.out.println("將N+2N個數異或計算得到personal1="+personal1);
		int p=personal1;
		for(;p<127;) {//一直向左移動,找到personal1剛開始爲1的位置也就是兩個數不同的位置。
			p=p<<1;
			youyicount++;
		}
		location=8-youyicount;//位置
		System.out.println("兩個唯一值二進制不同的位置爲 location="+location);
		loc=(int) Math.pow(2,location-1);//根據得到的位置,獲取需要的值
		System.out.println("根據location得到關鍵值 loc="+loc);
		for(int i=0,j=0,m=0;i<b.length;i++) {
			int t=b[i]&loc;
			if(t==0) {
				List1.add(b[i]);//兩個唯一的數,在第Location位置上不同,所以按照Location位置
//				                                              上0或1分爲兩組,可以將兩個唯一值分開,分開後,按照上面的方法分別求即可
			}else {
				List2.add(b[i]);
			}
		}
		for(int i=0;i<List1.size();i++) {
			int num=(int) List1.get(i);
			one=(int)List1.get(i)^one;
		}
		for(int i=0;i<List2.size();i++) {
			two=(int)List2.get(i)^two;
		}
		
		
		System.out.println("出現了奇數次的那一個數 one="+one);
		System.out.println("出現了奇數次的那一個數 two="+two);
	}

}


結果如圖:
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章