求排列A',使得advantage(A',B)最大
阿新 • • 發佈:2018-11-26
(這道題目是在不知道起個什麼名字好,就把題中關鍵的內容作為題目了)
題目
給定兩個長度相等都為n的陣列A和陣列B,定義advantage(A,B)等於A[i]>B[i]元素的個數,要求寫一個enhance函式,輸入A,B,返回一個排列A',使得advantage(A',B)最大,並給出時間複雜度。
舉例1
A=【2,7,11,15】,B=【1,10,4,11】
則advantage(A,B)=3(2>1,7<10,11>4,15>11)
利用你寫的enhance函式,可以得到A'=enhance(A,B)=【2,11,7,5】,使avantage(A',B)=4(2>1,11>10,7>4,15>11)
舉例2
A=【12,24,8,32】,B=【13,25,32,11】
A'=enhance(A,B)=【24,32,8,12】
avantage(A',B)=3(24>13,32>25,8<32,12>11)
思路
(宣告:這道題是同學問我的一道題,思路沒有驗證過,不知道對不對,希望看到這道題的你可以幫忙驗證一下)
- 求a陣列,那麼從a數組裡找數,和b陣列比較:
- b陣列第一個,a數組裡有沒有比他大的,
- 沒有的話,a陣列第一個數字就從老a數組裡最小的一個作為這個數(同時老a數組裡除去這個數【這一步操作的程式碼需要好好理解】
- 若有比他大的,就從所有比他大的數字裡邊找到最小的一個數字作為這個數字,(同時老a數組裡除去這個數)
- 沒有的話,a陣列第一個數字就從老a數組裡最小的一個作為這個數(同時老a數組裡除去這個數【這一步操作的程式碼需要好好理解】
- 以此類推
- b陣列第一個,a數組裡有沒有比他大的,
程式碼(遞迴實現)
思路已經明瞭,開始寫程式碼吧
雖然邏輯很清楚,實現出來的程式碼的邏輯你可能會看暈,所以這裡分佈來介紹我的程式碼(嫌麻煩的話直接看最終程式碼)
- 將目標陣列直接輸出的程式碼(實際上程式碼裡並沒有將數字儲存在數組裡,只是直接輸出數字)
- 將目標陣列儲存倒數組裡的程式碼(儲存到數組裡的順序是逆順序的)
- 將目標陣列儲存倒數組裡的程式碼(儲存到數組裡的順序是順序的)【最終程式碼】
將目標陣列直接輸出的程式碼(實際上程式碼裡並沒有將數字儲存在數組裡,只是直接輸出數字)
public static void shuzu(int[] a,int[] b){
if(a.length<=0){
return ;
}else{//這裡分情況討論
int flag=0;//設定標記,a裡有大於b的則為1,沒有則為0
int min_a=1000000;//記錄a數組裡最小的一個
int min_a_flag=0;//記錄a數組裡最小的一個的座標
int min=10000000;//假設有的話。用min來表示裡邊最小的一個
int min_flag=0;//記錄min的座標
for(int i=0;i<a.length;i++){
if(a[i]>b[0]){//總是比較b的第一個
flag=1;
if(a[i]<min){
min=a[i];
min_flag=i;
}
}
if(a[i]<min_a){
min_a=a[i];
min_a_flag=i;
}
}
if(flag==0){//如果沒有大的
//輸出a裡最小的
System.out.println(min_a);
//進行下一個遞迴(a、b陣列都減1個長度)
int[] a_new=new int[a.length-1];
int[] b_new=new int[a.length-1];
for(int i=0;i<a.length-1;i++){//將a減少一個長度,去掉那個小的數
if(i>=min_a_flag){
a_new[i]=a[i+1];
}else{
a_new[i]=a[i];
}
}
for(int i=1;i<a.length;i++){
b_new[i-1]=b[i];
}
shuzu(a_new,b_new);
}else{
//輸出大的裡邊的最小的
System.out.println(min);
//進行下一個遞迴(a、b陣列都減1個長度)
int[] a_new=new int[a.length-1];
int[] b_new=new int[a.length-1];
for(int i=0;i<a.length-1;i++){//將a減少一個長度,去掉那個小的數
if(i>=min_flag){
a_new[i]=a[i+1];
}else{
a_new[i]=a[i];
}
}
for(int i=1;i<a.length;i++){
b_new[i-1]=b[i];
}
shuzu(a_new,b_new);
}
}
}
將目標陣列儲存倒數組裡的程式碼(儲存到數組裡的順序是逆順序的)
我們在遞迴裡傳入一個引數:陣列c,每次遞迴都把那個數傳給陣列c,下標是陣列a的長度-1,因為每次遞迴陣列a都會減少1,這樣陣列c就是我們所求的陣列啦
public static void shuzu(int[] a,int[] b,int[] c){
if(a.length<=0){
return ;
}else{//這裡分情況討論
int flag=0;//設定標記,a裡有大於b的則為1,沒有則為0
int min_a=1000000;//記錄a數組裡最小的一個
int min_a_flag=0;//記錄a數組裡最小的一個的座標
int min=10000000;//假設有的話。用min來表示裡邊最小的一個
int min_flag=0;//記錄min的座標
for(int i=0;i<a.length;i++){
if(a[i]>b[0]){//總是比較b的第一個
flag=1;
if(a[i]<min){
min=a[i];
min_flag=i;
}
}
if(a[i]<min_a){
min_a=a[i];
min_a_flag=i;
}
}
if(flag==0){//如果沒有大的
//輸出a裡最小的
System.out.println(min_a);
c[a.length-1]=min_a;
//進行下一個遞迴(a、b陣列都減1個長度)
int[] a_new=new int[a.length-1];
int[] b_new=new int[a.length-1];
for(int i=0;i<a.length-1;i++){//將a減少一個長度,去掉那個小的數
if(i>=min_a_flag){
a_new[i]=a[i+1];
}else{
a_new[i]=a[i];
}
}
for(int i=1;i<a.length;i++){
b_new[i-1]=b[i];
}
shuzu(a_new,b_new,c);
}else{
//輸出大的裡邊的最小的
System.out.println(min);
c[a.length-1]=min;
//進行下一個遞迴(a、b陣列都減1個長度)
int[] a_new=new int[a.length-1];
int[] b_new=new int[a.length-1];
for(int i=0;i<a.length-1;i++){//將a減少一個長度,去掉那個小的數
if(i>=min_flag){
a_new[i]=a[i+1];
}else{
a_new[i]=a[i];
}
}
for(int i=1;i<a.length;i++){
b_new[i-1]=b[i];
}
shuzu(a_new,b_new,c);
}
}
}
將目標陣列儲存倒數組裡的程式碼(儲存到數組裡的順序是順序的)
為了保證c數組裡的數是順序的,我們在遞迴裡再傳入一個引數,初始a的長度,這個引數不隨著遞迴變化,這樣在c數組裡的下標改成length-a.length,所求的陣列就是順序的啦。
public static void shuzu(int[] a,int[] b,int[] c,int length){
if(a.length<=0){
return ;
}else{//這裡分情況討論
int flag=0;//設定標記,a裡有大於b的則為1,沒有則為0
int min_a=1000000;//記錄a數組裡最小的一個
int min_a_flag=0;//記錄a數組裡最小的一個的座標
int min=10000000;//假設有的話。用min來表示裡邊最小的一個
int min_flag=0;//記錄min的座標
for(int i=0;i<a.length;i++){
if(a[i]>b[0]){//總是比較b的第一個
flag=1;
if(a[i]<min){
min=a[i];
min_flag=i;
}
}
if(a[i]<min_a){
min_a=a[i];
min_a_flag=i;
}
}
if(flag==0){//如果沒有大的
//輸出a裡最小的
System.out.println(min_a);
c[length-a.length]=min_a;
//進行下一個遞迴(a、b陣列都減1個長度)
int[] a_new=new int[a.length-1];
int[] b_new=new int[a.length-1];
for(int i=0;i<a.length-1;i++){//將a減少一個長度,去掉那個小的數
if(i>=min_a_flag){
a_new[i]=a[i+1];
}else{
a_new[i]=a[i];
}
}
for(int i=1;i<a.length;i++){
b_new[i-1]=b[i];
}
shuzu(a_new,b_new,c,length);
}else{
//輸出大的裡邊的最小的
System.out.println(min);
c[length-a.length]=min;
//進行下一個遞迴(a、b陣列都減1個長度)
int[] a_new=new int[a.length-1];
int[] b_new=new int[a.length-1];
for(int i=0;i<a.length-1;i++){//將a減少一個長度,去掉那個小的數
if(i>=min_flag){
a_new[i]=a[i+1];
}else{
a_new[i]=a[i];
}
}
for(int i=1;i<a.length;i++){
b_new[i-1]=b[i];
}
shuzu(a_new,b_new,c,length);
}
}
}