博主今年研二,前几天舍友找实习投了阿里的内推,然后做了50分钟的测试题和一道编程题,测试题不用说,基本上就是智力题和性格测试,编程题限时30分钟,当时她没做出来,交卷后我俩讨论了很久,大概有了个结果,觉得可以把思路分享一下。
题目大致如下:
输入两个数字串
1.将数字串的某一位+1
2.将数字串的某一位-1
3.交换数字串中任意两个数字的位置
最终使得第一个数字串变成第二个数字串,请问最少需要多少次操作?
题意应该是将第一个数的各位数字通过交换位置、加减运算最终变成第二个数,求最小操作次数。
我们把这两个数字的各位存成两个数组
eg:
214
125
存成数组
a[]={2,1,4}
b[]={1,2,5}
题干给出的操作是三种,可以分为两类:交换、非交换。不论进行的是+运算还是-运算,操作次数都是|a[i]-b[i]|。要求最小操作次数,一定是先进行交换,再进行+-运算。
分析数组间元素的交换,是这道题重点。
a数列元素间需要进行交换时,一定是存在i,j (i≠j)∈[0,a.length),使得a[i] = b[j]。
当a[i] = b[i]时,a[i]元素达到平衡状态,此时还需要进行的操作为0,因此,a[i] ==b[i],是这道题的出口。
下面列出数组中交换可能存在的几种情况(按处理优先级):
(1)
a:1
b:1
需要进行n=0次交换,使得1个元素达到平衡状态;
(2)
a:1 2
b:2 1
需要进行n=1次交换,使得2个元素达到平衡状态;
(3)
a:2 1
b:3 2
需要进行n=1此操作,使得1个元素达到平衡状态。
这是我们最开始分析的三种情况,但马上发现不对,(3)状态之前还存在一种特殊情况,我用例子来说明:
a:9 5 7 8
b:5 7 8 5
此时{a,b}不存在(1)、(2)中所说的情况,但a中第二个元素5是应该与9交换还是与8进行交换?我们可以计算一下:
如果与9交换,此时总操作次数
n=1+1+1+4=7(包含+-操作)
如果与8进行交换,
此时总操作次数
n=1+1+4=6(包含+-操作)
由于交换位置不会导致数组所有元素和的大小,所以这里造成的n的不同与+-操作无关,而是因为在交换过程中出现了(2)情况,减少了一次操作。针对这种情况,我们提供一种解决方案,换一种思路考虑,在(3)中优先解决如下情况:
当a[i]是交换数(存在b[k]=a[i]),且存在j≠i,b[i]=a[j]。
此时优先交换a[i],在交换(3)中其他存在的还需要交换的元素。
当执行完以上需要交换的操作后,就可以最后进行
+-操作了。
最后附上我写的JAVA代码,供大家参考。这个代码我测试了一些用例,暂时没有发现什么错误,如果大家发现代码有什么情况没有考虑可以告诉我,或者还有什么更简单的思路或者更优化的代码结构可以相互交流。博主不是计算机专业,java基础不是很好,代码写得不好,大家不要怪哈~~
java代码:
public class Test {
public static void main(String[] args) {
int x = 214;
int y = 125;
int a[] = toArray(x);
int b[] = toArray(y);
System.out.println(rec_exchange(a, b));
}
public static int[] toArray(int x){
String str = String.valueOf(x);
int a[] = new int[str.length()];
for(int i=0;i<a.length;i++){
//a[i] = Integer.parseInt((String) str.subSequence(i, i+1));
a[i] = Integer.parseInt(str.substring(i, i+1));
}
return a;
}
public static int rec_exchange(int[] a, int[] b) {
int i;
int j;
int num=0;//次数
if(a==null || b==null){
return 0;
}
if(a.length != b.length){
return -1;
}
//第(1)种情况
for(i=0;i<a.length;i++){
if(a[i]==b[i]){
a = newArray(a,i);
b = newArray(b,i);
return num + rec_exchange(a, b);
}
}
//第(2)种情况
for(i=0;i<a.length;i++){
for(j=0;j<b.length;j++){
if(i!=j && a[i]==b[j] && a[j]==b[i]){
num++;
a = newArray(a,j);
a = newArray(a,i);
b = newArray(b,j);
b = newArray(b,i);
return num + rec_exchange(a, b);
}
}
}
//第(3)种的优先情况
for(i=0;i<a.length;i++){
for(j=0;j<b.length;j++){
for(int z=0;z<b.length;z++){
if(i!=j && i!=j && j!=z && a[i]==b[j] && a[j]==b[z]){
num++;
a = exchangeSpace(a, i, j);
a = newArray(a,j);
b = newArray(b,j);
return num + rec_exchange(a, b);
}
}
}
}
//第3种的其他情况
for(i=0;i<a.length;i++){
for(j=0;j<b.length;j++){
if(a[i]==b[j]){
num++;
a = exchangeSpace(a, i, j);
a = newArray(a,j);
b = newArray(b,j);
return num + rec_exchange(a, b);
}
}
}
//+-运算
for(i=0;i<a.length;i++){
int diff=0;
diff = a[i]-b[i];
if(diff>0){
num += diff;
}
if(diff<0){
num -= diff;
}
}
return num;
}
public static int[] exchangeSpace(int[] a,int i,int j){
int t;
t = a[i];
a[i] = a[j];
a[j] = t;
return a;
}
public static int[] newArray(int a[], int i){
if(a.length<=1){
return null;
}else{
int[] arr = new int[a.length-1];
int count=0;
for(int j=0;j<a.length;j++){
if(j!=i){
arr[count]=a[j];
count++;
}
}
return arr;
}
}
}