從德問上面看到別人提問的一道面試題,做了一下:
面試題:交換數字位置得到相對最大值
前段時間遇到的一個面試題:
給你一個數,允許你選擇兩個數字交換位置,每個數只能交換一次位置,請交換得到儘可能的最大值,寫出演算法(請注意考慮有重複數位情況)。
例如:
13792 -> 97312 (每個數字只能交換一次,所以無法得到 97321,盡量就ok了)
5881 -> 8851 (要交換5和第二個8,不要交換為了 8581)
-------------------分割線--------------------
我也來說說思路:
1、第一個數字起,從剩下的、沒有進行交換過的數字中找最大的數字。如果有重複最大數字,則與最後一個重複的數字交換。以此迭代,直到有一半數字已經交換過了(因為每一次交換,會用掉兩個數位交換器會),演算法結束。
時間複雜度是O(n^2),不知道有沒有線性時間的解法。
#include<stdio.h>#include<memory.h>#define N 100int A[N] ; //存放數字bool B[N] ; //記錄數字是否已經交換過int main(void){int i,j,t,n ;int nMax,nMaxIndex,nTemp ;freopen("in.txt","r",stdin) ; //重新導向,便於測試資料while(scanf("%d",&n) != EOF){memset(A,0,sizeof(A)) ;memset(B,0,sizeof(B)) ;for(i = 1 ; i <= n ; ++i){scanf("%d",&A[i]) ;}t = n/2 ; //只需要交換一半的數字就可以了for(i = 1 ; i <= t ; ++i){if(false == B[i]){nMax = A[i] ;nMaxIndex = i ;for(j = i+1 ; j <= n ; ++j){if(false == B[j] && A[j] >= nMax) //用大於等於處理有重複數位情況{nMax = A[j] ;nMaxIndex = j ;}}if(nMax != A[i]) //如果需要交換的兩個數字相等,即無需交換,不浪費交換器會{B[i] = true ;B[nMaxIndex] = true ;nTemp = A[i] ;A[i] = A[nMaxIndex] ;A[nMaxIndex] = nTemp ;}}}//輸出結果:for(i = 1 ; i <= n ; ++i){printf("%d",A[i]) ;}printf("\n") ;}return 0 ;}