百度二面算法手撕:将一个整数数组[a1,a2,a3,a4...]中的所有元素拼接起来,找到最大的值

百度二面算法手撕:将一个整数数组[a1,a2,a3,a4...]中的所有元素拼接起来,找到最大的值


前言

昨天我在刷牛客的时候,看到一个牛友分享了百度二面的算法手撕题:将一个整数数组[a1,a2,a3,a4…]中的所有元素拼接起来,返回最大的值,我对该题很感兴趣,又参考了力扣 LCR 164. 破解闯关密码的解法,自己写了代码,如有错误,期望大佬纠正,万分感谢!


提示:以下是本篇文章正文内容,下面案例可供参考

一、寻找规律

假若有一个数组[3,30,34,5,9],怎么才能使其拼接最大呢?我们可以将整数转换为字符拼接比较,例如3和30,拼接结果有330和303,330比303大,因此3应该在30前面,我们从后往前遍历一次进行比较交换可以将拼接的第一位确定

从最后一位开始向前遍历第一轮遍历确定第一位的值
[ 3 , 30 , 34 , 5 , 9]
9和5拼接比较 ‘95’>‘59’ 进行交换后的结果[ 3 , 30 , 34 , 9 , 5 ]
‘934’>‘349’ 结果 [3 , 30 , 9 , 34 , 5]

第一轮后的结果[ 9 , 3 , 30 , 34 , 5 ]
我们发现每一轮确定一个位置,那么下一轮就要对[ 3 , 30 , 34 , 5 ]进行排序

当位置都确定后最大值也就出现了,我们很容易发现这是冒泡排序,和数组排序整数直接比较不同,该题我们比较的是拼接的字符串大小,而排序是一样的。而冒泡排序时间复杂度较高,我们选择用快速排序来进行排序

二、代码实现

 public static String findMax(int[] arr) {
        int n = arr.length;
        String[] s = new String[n];
        for (int i = 0; i < n; i++) {
            s[i] = String.valueOf(arr[i]);
        }
//        快速排序
        quickSort(s, 0, n - 1);
        StringBuilder stringBuilder = new StringBuilder();
        for (String s1 : s) {
            stringBuilder.append(s1);
        }
        return String.valueOf(stringBuilder);
    }

    private static void quickSort(String[] s, int l, int r) {
        if (l >= r) return;
//        l作为分区点,i为左指针,j为右指针
        int i = l, j = r;
        while (i < j) {
//           右指针向左遍历直到s[j]+s[l]>s[l]+s[j],需要先遍历右指针,当最后i==j时由于j先进行的遍历那么s[j]一定是要在前面的值,与分区点进行交换刚刚好
            while (i < j && (s[j] + s[l]).compareTo(s[l] + s[j]) <= 0) {
                --j;
            }
            ;
//           左指针向左遍历直到s[i]+s[l]<s[l]+s[i]
            while (i < j && (s[i] + s[l]).compareTo(s[l] + s[i]) >= 0) {
                i++;
            }
            swap(s, i, j);
        }
        swap(s, l, j);
        quickSort(s, l, i - 1);
        quickSort(s, i + 1, r);
    }

    //元素交换
    private static void swap(String[] s, int i, int j) {
        String tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值