其他分享
首页 > 其他分享> > LeetCode 1363. 形成三的最大倍数

LeetCode 1363. 形成三的最大倍数

作者:互联网

LeetCode 1363. 形成三的最大倍数

题目来源

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-multiple-of-three/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目描述

给你一个整数数组 digits,你可以通过按任意顺序连接其中某些数字来形成 3 的倍数,请你返回所能得到的最大的 3 的倍数。
由于答案可能不在整数数据类型范围内,请以字符串形式返回答案。
如果无法得到答案,请返回一个空字符串。

示例 1:

输入:digits = [8,1,9]
输出:"981"

示例 2:

输入:digits = [8,6,7,1,0]
输出:"8760"

示例 3:

输入:digits = [1]
输出:""

示例 4:

输入:digits = [0,0,0,0,0,0]
输出:"0"

提示:

1 <= digits.length <= 10^4
0 <= digits[i] <= 9
返回的结果不应包含不必要的前导零。

思路:

首先有一个规律:如果一个数的每一位之和是3的倍数,那个这个数可以被3整除。
假设整个数组之和是3的倍数:

①如果要得到的最大的 3 的倍数,那么要得到这个最大的3的倍数,可以对数组进行排序,最后按顺序输出这个数组即可。例如如果是从小到大排序,那么倒序输出这个数组就是最大的3的倍数。

接下来要解决的问题是如果整个数组之和不是3的倍数:

假设数组之和是sum,remainder = sum%3 != 0,可以考虑到remainder = 1 或者remainder=2。

②如果remainder=1,那么我们需要删除一个最小的且余3为1的即可、或者删除两个最小的且余3为2的数字即可。

③如果remainder=2,那么我们需要删除一个最小的且余3为2的即可、或者删除两个最小的且余3为1的数字即可。

代码如下:

public String largestMultipleOfThree(int[] digits) {
    // 对数组求和
    int sum = 0;
    for (int i : digits) {
        sum += i;
    }
    // 情况①,倒序返回数组即可
    if (sum % 3 == 0) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = digits.length - 1; i >= 0; i--) {
            stringBuilder.append(digits[i]);
        }
        return stringBuilder.toString();
    }
    // 从小到大排序
    Arrays.sort(digits);
    int remainder = sum % 3;

    // 情况②
    if (remainder == 1) {
        int[] rem_2 = new int[2];
        rem_2[0] = -1;
        rem_2[1] = -1;
        // 遍历整个数组
        for (int i = 0; i < digits.length; i++) {
            // 情况②中的第一种情况。如果找到一个数字余数是1,删除这个数字即可
            if (digits[i] % 3 == 1) {
                return removeAndPrintResult(digits, i, -1);
            }
            // 情况②中的第二种情况。如果这个数字余数是2,记录下来,如果找到了两个余数是2的数字,删除这两个数字即可
            if (digits[i] % 3 == 2) {
                // 保存第一个余数是2的数字
                if (rem_2[0] == -1) {
                    rem_2[0] = i;
                }
                // 保存第二个余数是2的数字
                else if (rem_2[1] == -1) {
                    rem_2[1] = i;
                }
            }
        }
        // 如果找到了两个余数是2的数字,删除这俩数组就是答案
        if (rem_2[0] != -1 &&
                rem_2[1] != -1) {
            return removeAndPrintResult(digits, rem_2[0],
                    rem_2[1]);
        }
    }
    // 情况③。如果余数是2
    else if (remainder == 2) {
        int[] rem_1 = new int[2];
        rem_1[0] = -1;
        rem_1[1] = -1;
        // 遍历数组
        for (int i = 0; i < digits.length; i++) {
            // 情况③中的第一种情况。找到一个余数是2的数字,删除即可
            if (digits[i] % 3 == 2) {
                return removeAndPrintResult(digits, i, -1);
            }
            // 情况③中的第二种。尝试寻找两个余数是1的数组,删掉这俩数组也可以
            if (digits[i] % 3 == 1) {
                if (rem_1[0] == -1) {
                    rem_1[0] = i;
                } else if (rem_1[1] == -1) {
                    rem_1[1] = i;
                }
            }
        }
        if (rem_1[0] != -1 &&
                rem_1[1] != -1) {
            return removeAndPrintResult(digits, rem_1[0],
                    rem_1[1]);
        }
    }
    // 其余情况没有答案
    return "";
}
// 删除指定位置的数字构建字符串。
private String removeAndPrintResult(int[] digits,
                                    int ind1, int ind2) {
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = digits.length - 1; i >= 0; i--) {
        if (i != ind1 && i != ind2) {
            stringBuilder.append(digits[i]);
        }
    }
    return stringBuilder.toString();
}
千古盈亏休问 发布了25 篇原创文章 · 获赞 15 · 访问量 1万+ 私信 关注

标签:digits,int,倍数,数组,rem,余数,remainder,LeetCode,1363
来源: https://blog.csdn.net/a1033025319/article/details/104525592