數組中的趣味題(一)


  無論是參加面試還是筆試,數組都是常考的內容,並且考察數組的知識往往結合着比較有意思的算法。在這里參照網上的資料和平時看過的相關書籍總結一下,作為自己的面試復習材料吧。我知道這個總結肯定有遺漏或者是不對的地方,希望大家看到可以優化和改正的的地方,幫幫忙給點新思路吧。謝謝大家~~

1.求數組中的最大值(最小值)


問題描述:給定一個整數數組arr,找出其中的最大值(最小值)。

解決思路:傳統的方法就是遍歷一次數組即可得到最大值(最小值),時間復雜度是O(N);現在說另外一個思路利用二分,即將數組分成元素數目接近相等的兩部分,然后分別找到兩個部分的的最大值(最小值),最后合並,比較兩個部分的最大值(最小值),即可得到最終的最大值(最小值)。

代碼:

FindMax 
 1 int FindMax(int *arr,int l,int r)
 2 {
 3     if(l == r)
 4     {
 5         return arr[l];
 6     }
 7     int mid = (l+r)/2;
 8     int LMAX,RMAX;
 9     LMAX = FindMax(arr,l,mid);
10     RMAX = FindMax(arr,mid+1,r);
11     return max(LMAX,RMAX);
12 }

2.求數組中出現次數超過一半的元素


問題描述:整數數組arr中,一定存在一個數x,x在數組arr中出現的次數過半,請找出這個數x。

解決思路:既然x在數組中出現的個數過半,那么若將數組arr排序,顯然數組中arr[N/2]一定是要找的x(N數組arr中元素的個數)。這個思路的時間復雜度取決於排序算法的時間復雜度,因此整個算法的時間復雜度達到O(N*logN)是沒有問題的。既然x在數組arr中出現的次數過半,那么在遍歷數組的過程中若每次遇到與x不同的數,x出現的數目-1,出現x,則x出現的數目+1,那么到最后剩下的一定是x。這種情況下,只需要遍歷一次數組,時間復雜度是O(N),但是,難點是我們事先不知道x是什么,那么算法怎么實現呢?看看代碼就明白啦~~

代碼:

Find
 1 int Find(int *arr,int n)
 2 {
 3     int tmp = arr[0];
 4     int count = 1;//計數器
 5     for(int i = 1 ; i < n ; i++)
 6     {
 7         if(count == 0)
 8         {
 9             tmp = arr[i];
10             count = 1;
11         }
12         else if(tmp == arr[i])
13         {
14             count++;
15         }
16         else
17         {
18             count--;
19         }
20     }
21     return tmp;
22 }

3.求數組中元素間的最近距離(一)


問題描述:數組arr[]中存在N個元素(數組中N個元素沒有范圍),找到這樣的a和b,使得abs(a,b)的值最小。

解決思路:這是個比較簡單的問題了,思路也很容易想到,只需要將arr進行排序,這時數組中元素的最短距離只可能是相鄰的兩個元素之間,這個算法的時間復雜度是:O(N*logN)。如果不對數組進行排序,那么就需要枚舉數組中的每兩個元素了,求出最小距離,時間復雜度是O(N*N)。

代碼:

MinDistance
 1 int MinDistance(int *arr,int n)
 2 {
 3     int tmp_MIN = INF;
 4     //假設INF是arr中兩個數相加能得到的最大值
 5     sort(arr,arr+n);
 6     for(int i = 0 ; i < n-1; i++)
 7     {
 8         if(arr[i+1] - arr[i] < tmp_MIN)
 9         {
10             tmp_MIN = arr[i+1] - arr[i];
11         }
12     }
13     return tmp_MIN;
14 }

4.求數組中元素間的最近距離(二)


問題描述:和上一個問題相似,區別是arr中的數組元素的取值范圍的。

解決思路:既然加了一個條件,那么看來就是利用這個條件進行優化了。既然數組中的元素有了范圍,不妨先假設數組中值在0~100之間,那么我們可以這樣做,申請一個數組bool fuzhu[100],這樣遍歷一遍數組,記錄arr中出現的元素,假設arr中包含4,那么arr[4]=1,然后在遍歷一遍fuzhu,fuzhu[i]值為1,表示i存在於arr中,這樣計算“相鄰”的fuzhu[]=1的元素,計算出最小距離。用一個大家看書時比較不願意看到的詞:經分析,時間復雜度是O(N+M),其中M是aar中元素的所在區間大小。

代碼:

MinDistance
 1 int MinDistance(int *arr,int n)
 2 {
 3     bool fuzhu[101];
 4     int first,second;
 5     int tmp_MIN = INF;
 6     memset(fuzhu,false,sizeof(fuzhu));
 7     //遍歷找出在arr出現的數
 8     for(int i = 0 ; i < n ; i++)
 9     {
10         fuzhu[arr[i]] = true;
11     }
12     int j = 0;
13     while(j < 101 && !fuzhu[j])
14     {
15         j++;
16     }
17     first = j++;//獲取fuzhu中第一個不為0的數
18     while(j < 101 && !fuzhu[j])
19     {
20         j++;
21     }
22     second = j++;//獲取fuzhu中第二個不為0的數
23     while(1)
24     {
25         if(second - first < tmp_MIN)
26         {
27             tmp_MIN = second - first;
28         }
29         while(j < 101 && !fuzhu[j])
30         {
31             j++;
32         }
33         if(j > 100) break;
34         first = second;
35         second = j++;
36     }
37     return tmp_MIN;
38 }

小結:大家看后,肯定會說arr中數組范圍也可能是負數啊,那怎么辦呢?注意了,這個題要求的是,最近距離。下標雖然不能為負,但是只要移位存儲就完事了嗎!畢竟只需要最小距離啊,平行移動不影響最小距離。比如arr中元素的范圍是-100~~100,那么只需要當出現-100,對應的fuzhu[-100+100] = fuzhu[0] = true。不就可以了嗎?

5.求兩個數組中的相同元素


問題描述:現在有兩個已經排好序的整數數組arr1和arr2,找出兩個數組中的相同元素。

解決思路:既然已經排好序了,那么問題就簡單了,假設arr1[2]和arr2[4]相等,那么搜索arr1[3]只需要和arr2中下標4及以后的元素比較。如果arr1和arr2中元素的個數分別是N和M,那么這個算法的時間復雜度是O(N+M),不妨先看看代碼。

代碼:

 

FindSame
 1 // 找出兩個數組的相同元素
 2 void FindSame(int *arr1, int *arr2,int n,int m)
 3 {    
 4     int i = 0;    
 5     int j = 0 ;    
 6     while (i < n && j < m)    
 7     {        
 8         if (arr1[i] < arr2[j])            
 9             ++i;        
10         else if(arr1[i] == arr2[j])        
11         {            
12             cout<<arr1[i]<<endl;
13             ++i;            
14             ++j;    
15         }       
16         else//arr1[i] > arr2[j]    
17             ++j ;   
18     }
19 }

小結:對於這個問題arr1和arr2數組都已經是排好序的,那么如果兩個數組都不是排好序的呢??后來在網上查了點資料,發現這樣一個哈希的思路:遍歷一遍arr1,建立哈希表,然后遍歷一遍arr2,看看哪一個元素存在於哈希表中。這樣一來時間復雜度還是O(N+M),但是多引入了O(N)的空間復雜度。在這里:求高手給出哈希的C++代碼!!!

學習中的一點總結,歡迎拍磚哦^^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM