ByteDance面试题:组合新数字

描述
现在有一个数组a,你可以从里面取任意个数字,用这些数字组成一个新的数字,例如5,12,3三个数字可以组成新数字5123。
题目需要你求出最大的能被3整除的新组合数字。

  1. 0< |a| <1000
  2. 0<= a[i] <=1000 (0<= i < |a|)
  3. 题目保证数据一定有解

在线评测地址

样例1:
输入:[1,2,2]
输出:“21”

样例2:

输入:[1,2,4,6]
输出:"642"

样例3:

输入:[3,0,6,9]
输出:"9630"

解题思路
按照题意的思路去考虑取哪些数,这样情况会比较复杂,解题费时。可以考虑不取哪些数。 可以想到,当数组和模三余0时,必定全取; 当数组和模三余1时,不取一个模三余1的数,或者不取两个模三余2的数; 当数组和模三余2时,不取一个模三余2的数,或者不取两个模三余1的数。

算法流程

  • 列表项目计算数组和模三的余数sum,将数组按数值从小到大排序并遍历,第一个模三余数等于sum的数不取,其他数均取
  • 将数组内所有值进行排序得到最大值字符串ans_1(自定义排序,比较数字a和b不同顺序连接得到的两个字符串ab和ba大小决定其排序)
  • 将数组按数值从小到大遍历,第一个和第二个模三余数等于(3-sum)的数不取,其他数均取,同上得到ans_2
  • 若ans_2均存在,返回max(ans_1,ans_2),否则返回ans_1

复杂度分析

  • 时间复杂度:O(nmlogn) n为数组长度,m为数组中数字位数,因为排序时复杂度为nlogn,且在其基础上定义了字符串比较大小
  • 空间复杂度:O(nm) 需要存下将数组中数组转化为字符串的所有字符

源代码

public class Solution {
    /**
     * @param a: the array in problem.
     * @return: represent the new number.
     */
    
    public String Combine(List<Integer> a) {
        int n = a.size();
        int flag = 0, sum = 0;
        List<String> tmp_1 = new ArrayList<>(), tmp_2 = new ArrayList<>();
        String ans_1 = "", ans_2 = "";
        Collections.sort(a);
        //求数组和模三的余数sum
        for (int i = 0; i < n; i++) {
            sum += a.get(i);
        }
        sum %= 3; 
        for (int i = 0; i < n; i++) {
            if(flag == 0 && a.get(i)%3 == sum && sum != 0){
                //第一个模三余数等于sum的数不取
                flag = 1;
            }
            else {
                tmp_1.add(a.get(i) + "");
            }
        }
        Collections.sort(tmp_1, c);
        for(int i = 0; i < tmp_1.size(); i++) {
            ans_1 += tmp_1.get(i);
        }
        flag = 0;
        for (int i = 0; i < n; i++) {
            if(flag < 2 && a.get(i)%3 == 3 - sum) {
                //第一个和第二个模三余数等于3 - sum的数不取
                flag++;
            }
            else {
                tmp_2.add(a.get(i) + "");
            }
        }
        if (flag == 2) {
            Collections.sort(tmp_2, c);
            for(int i = 0; i < tmp_2.size(); i++) {
                ans_2 += tmp_2.get(i);
            }
            if((ans_2.length() > ans_1.length()) || (ans_1.length() == ans_2.length() && ans_2.compareTo(ans_1) > 0))
                return ans_2;
        }
        return ans_1;
    }
    //自定义排序函数
    Comparator<String> c = new Comparator<String>() {
        @Override
        public int compare(String x, String y) {
            String xy = x + y, yx = y + x;
            return yx.compareTo(xy);
        }
    };
}

更多题解参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值