1. 程式人生 > >1.2 如何找出唯一成對的數(4種解法)

1.2 如何找出唯一成對的數(4種解法)

java實現 輔助 用c語言實現 urn 循環嵌套 如何 原來 lock 設計

作者:acDream_
來源:CSDN
原文:https://blog.csdn.net/acDream_/column/info/32487

原文是用Java實現的,自己理解後用C語言實現,記錄下來。

Problem:
1-1000這1000個數放在含有1001個元素的數組中,只有唯一的一個元素值重復,其他均只出現一次。設計一個算法,將它找出來,你能否設計一個算法實現?

思路1(最先想到的):

首先也是最暴力的方法就是一個循環嵌套一個循環,一個一個去找

時間復雜度為O(n²)

下面是實現的代碼:

 1 #include<stdio.h>
 2 
 3 int main()
4 { 5 int a[11]={1,2,3,4,4,5,6,7,8,9}; 6 int i,j; 7 int size=sizeof(a)/sizeof(a[0]); //sizeof(a)得到的是 整型長度4*元素個數 8 for(i=0;i<size;i++) 9 for(j=i+1;j<size;j++) 10 if(a[i]==a[j]) 11 printf("%d\n",a[i]); 12 13 return 0; 14
}

思路2:

另外開辟一個大小為1001的數組arr,遍歷原來的數組,原來數組中的數就是arr中的下標,若遇到一個數就將對應arr的下標位置對應的值加一就行。然後遍歷arr數組,若遇到下標位置對應的值為2的時候,輸出下標就行

時間復雜度為O(n)

下面是實現的代碼:

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int i;
 6     int a[11]={1,2,3,4,4,5,6,7,8,9};
 7     int b[11]={0};
 8     int size=sizeof(a)/sizeof
(a[0]); 9 for(i=0;i<size;i++) 10 { 11 b[a[i]]++; 12 13 if(b[i]==2) 14 printf("%d\n",i); 15 } 16 return 0; 17 }

思路3:

使用異或來找出唯一成對的數,這種算法的效率應該是最高的了,而且不需要輔助空間

先來說一下異或的規則:

a^a=0

a^0=a

然後我們的思路是將這1001個數全部異或起來,那麽就會把相同的數給變成0了,那麽怎麽辦呢?

我們可以再次將該數與1-1000之間的數給異或起來

那麽不重復的數都會變成0,而重復的數不會變成0

時間復雜度為O(n)

下面是實現的代碼:

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int i,s1=0,s2=0;
 6     int a[11]={1,2,3,4,4,5,6,7,8,9};
 7     int size=sizeof(a)/sizeof(a[0]);//size=11
 8     for(i=0;i<size;i++)
 9         s1=s1^a[i];//s=5
10     for(i=1;i<size-1;i++)
11         s2=s2^i;
12         
13     printf("%d\n",s1^s2);
14 
15     return 0;
16 }

s1=(1000個數^) ^ 重復數

s2=1000個數^

s1^s2=(1000個數^) ^ 重復數 ^ (1000個數^) = 0 ^ 重復數 = 重復數

思路4:

數學求和法,因為只有一個數字重復一次,而數又是連續的,根據累加和原理,對數組的所有項求和,然後減去1至N-1的和,即為所求的重復數。

時間復雜度為O(n)。
下面是實現的代碼:

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int i,s1=0,s2=0;
 6     int a[11]={1,2,3,4,4,5,6,7,8,9};
 7     int size=sizeof(a)/sizeof(a[0]);//size=11
 8     for(i=0;i<size;i++)
 9         s1=s1+a[i];
10     for(i=1;i<size-1;i++)
11         s2=s2+i;
12         
13     printf("%d\n",s1-s2);
14 
15     return 0;
16 }

1.3 找出落單的數,這樣編程就對了

Problem:

一個數組裏除了某一個數字外,其他的數字都出現了兩次。請寫程序找出這個只出現一次的數字。

Hint:

這個問題比上一個問題(如何找出唯一成對的數)簡單多了,這裏直接異或就行了

實現代碼:

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int i,s=0;
 6     int a[11]={1,1,2,3,4,2,3,4,5,6,5};
 7     int size=sizeof(a)/sizeof(a[0]);//size=11
 8     for(i=0;i<size;i++)
 9         s=s^a[i];
10         
11     printf("%d\n",s);
12 
13     return 0;
14 }

1.2 如何找出唯一成對的數(4種解法)