大数和中极值位距离 | 豆包MarsCode AI刷题

105 阅读3分钟

思路: 这个和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. 字符串反转与长度计算

首先,代码计算了两个字符串的长度len1len2,并确定了较长的字符串长度maxlen和较短的字符串长度minlen。接着,代码将两个字符串分别反转,以便从低位到高位进行逐位相加。

2. 逐位相加

代码通过一个循环,从低位到高位逐位相加两个字符串的对应字符,并将结果存储在数组res中。如果两个字符串长度不同,则较短的字符串在高位补0。相加过程中,代码还处理了进位问题。

3. 寻找极值

在相加完成后,代码遍历结果数组res,找出其中的最大值max和最小值min。然后,代码分别记录了最大值和最小值在数组res中的所有位置,分别存储在maxListminList中。

4. 计算最小距离

最后,代码通过嵌套循环,计算了maxListminList中所有位置之间的距离,并找出其中的最小值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);
            }
        }

这里的寻找极值距离的算法应该还有可以改进的地方,这段代码可以通过优化来提高性能。当前的实现方式是使用嵌套循环来计算maxListminList中所有位置之间的距离,并找出其中的最小值。这种做法的时间复杂度是O(n^2),其中nmaxListminList的长度之和。我觉得应该可以用动态规划或双指针的方法,还在探索😚