思路: 这个和leetcode大数相加的题目解法类似,都是数值很大,平常的类型装不下。所以需要模拟高精度计算,但是这个不需要我们计算最终的数值,只要知道相加后的结果就行,关注的是极值,所以可以将字符串反转过来,然后再顺序计算他,还要记得进位。
import java.util.ArrayList;
import java.util.List;
public class 大数和中极值位距离 {
public static int solution(String string1, String string2) {
int len1=string1.length(),len2=string2.length();
int maxlen=Math.max(len1,len2),minlen=len1+len2-maxlen;
String revstr1=new StringBuilder(string1).reverse().toString();
String revstr2=new StringBuilder(string2).reverse().toString();
int [] res=new int[maxlen+1];
int next=0,temp;
for(int i=0;i<minlen;i++){
temp=(int)(revstr1.charAt(i)+revstr2.charAt(i)-2*'0')+next;
next=temp/10;
res[i]=temp%10;
}
String longstr=null;
if (maxlen==len1){
longstr=revstr1;
}else{
longstr=revstr2;
}
for (int i=minlen;i<maxlen;i++){
temp=(int)(longstr.charAt(i)-'0')+next;
next=temp/10;
res[i]=temp%10;
}
int end=maxlen+1;
if (next==0){
end=maxlen;
}
int min=100,max=-1;
int myabs;
for (int i=0;i<end;i++){
if(res[i]>=max){
max=res[i];
}
if(res[i]<=min){
min=res[i];
}
}
//此时,我们就知道里面的极值了min,max是什么
/*System.out.println("反转相加:"+Arrays.toString(res));
System.out.println("max:"+max+" min:"+min);*/
List<Integer> maxList=new ArrayList<>(),minList=new ArrayList<>();
for(int i=0;i<end;i++){
if(max==res[i]){
maxList.add(i);
}
if(min==res[i]){
minList.add(i);
}
}
/*System.out.println("maxlist:"+maxList);
System.out.println("minlist:"+minList);*/
myabs=100000;
for(int i: maxList){
for(int j: minList){
temp=Math.abs(i-j);
myabs= Math.min(temp, myabs);
}
}
if(myabs>0){
myabs--;
}
return myabs;
}
public static void main(String[] args) {
// You can add more test cases here
System.out.println(solution("111", "222") == 0);
System.out.println(solution("111", "34") == 1);
System.out.println(solution("5976762424003073", "6301027308640389") == 6);
System.out.println(solution("11000001","44334434334444344333")==0);
}
}
代码的主要功能可以分为以下几个步骤:
1. 字符串反转与长度计算
首先,代码计算了两个字符串的长度len1和len2,并确定了较长的字符串长度maxlen和较短的字符串长度minlen。接着,代码将两个字符串分别反转,以便从低位到高位进行逐位相加。
2. 逐位相加
代码通过一个循环,从低位到高位逐位相加两个字符串的对应字符,并将结果存储在数组res中。如果两个字符串长度不同,则较短的字符串在高位补0。相加过程中,代码还处理了进位问题。
3. 寻找极值
在相加完成后,代码遍历结果数组res,找出其中的最大值max和最小值min。然后,代码分别记录了最大值和最小值在数组res中的所有位置,分别存储在maxList和minList中。
4. 计算最小距离
最后,代码通过嵌套循环,计算了maxList和minList中所有位置之间的距离,并找出其中的最小值myabs。如果最小距离大于0,代码将其减1,以符合题目要求的“中极值位距离”。
5. 测试用例
在main方法中,代码提供了几个测试用例,用于验证solution方法的正确性。每个测试用例都打印了方法的返回值,并与预期结果进行比较。
代码中使用了StringBuilder来反转字符串,以及ArrayList来存储极值的位置,这些都是Java中常用的工具类,能够有效地提高代码的可读性和可维护性。
不足的地方
for(int i: maxList){
for(int j: minList){
temp=Math.abs(i-j);
myabs= Math.min(temp, myabs);
}
}
这里的寻找极值距离的算法应该还有可以改进的地方,这段代码可以通过优化来提高性能。当前的实现方式是使用嵌套循环来计算maxList和minList中所有位置之间的距离,并找出其中的最小值。这种做法的时间复杂度是O(n^2),其中n是maxList和minList的长度之和。我觉得应该可以用动态规划或双指针的方法,还在探索😚