(这道题目是在不知道起个什么名字好,就把题中关键的内容作为题目了)
题目
给定两个长度相等都为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数组里除去这个数)
- 以此类推
- 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);
}
}
}