同余问题-三整除系列

2020-05-11 10:50:50

1363. 形成三的最大倍数

问题描述:

给你一个整数数组 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
返回的结果不应包含不必要的前导零。

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

问题求解:

一个数的各个位的和如果可以整除3,那么这个数就可以整除3。

如果sum % 3 == 1,那么可以去掉一个mod 3 == 1的数,或者去掉两个mod 3 == 2的数。

如果sum % 3 == 2,那么可以去掉一个mod 3 == 2的数,或者去掉两个mod 3 == 1的数。

    public String largestMultipleOfThree(int[] digits) {
        Map<Integer, Integer> map = new HashMap<>();
        Map<Integer, List<Integer>> mod = new HashMap<>();
        int sum = 0;
        for (int d : digits) {
            sum += d;
            map.put(d, map.getOrDefault(d, 0) + 1);
            if (d % 3 == 1) {
                if (!mod.containsKey(1)) mod.put(1, new ArrayList<>());
                mod.get(1).add(d);
            }
            if (d % 3 == 2) {
                if (!mod.containsKey(2)) mod.put(2, new ArrayList<>());
                mod.get(2).add(d);
            }
        }
        if (sum % 3 == 1) {
            List<Integer> m1 = mod.getOrDefault(1, new ArrayList<>());
            List<Integer> m2 = mod.getOrDefault(2, new ArrayList<>());
            Collections.sort(m1);
            Collections.sort(m2);
            if (m1.size() > 0) map.put(m1.get(0), map.get(m1.get(0)) - 1);
            else if (m2.size() > 1) {
                map.put(m2.get(0), map.get(m2.get(0)) - 1);
                map.put(m2.get(1), map.get(m2.get(1)) - 1);
            }
            else return "";
        }
        if (sum % 3 == 2) {
            List<Integer> m1 = mod.getOrDefault(1, new ArrayList<>());
            List<Integer> m2 = mod.getOrDefault(2, new ArrayList<>());
            Collections.sort(m1);
            Collections.sort(m2);
            if (m2.size() > 0) map.put(m2.get(0), map.get(m2.get(0)) - 1);
            else if (m1.size() > 1) {
                map.put(m1.get(0), map.get(m1.get(0)) - 1);
                map.put(m1.get(1), map.get(m1.get(1)) - 1);
            }
            else return "";
        }
        List<Integer> nums = new ArrayList<>();
        for (int key : map.keySet()) {
            for (int i = 0; i < map.get(key); i++) nums.add(key); 
        }
        Collections.sort(nums);
        if (nums.size() == 0) return "";
        else if (nums.get(nums.size() - 1) == 0) return "0";
        else {
            StringBuffer sb = new StringBuffer();
            for (int i = nums.size() - 1; i >= 0; i--) sb.append(nums.get(i));
            return sb.toString();
        }
    }

  

1341. 组合新数字

问题描述:

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

样例

样例1:

输入:[1,2,2]
输出:"21"

样例2:

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

样例3:

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

注意事项

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

问题求解:

这一题算是上面问题的普通版本,上面的问题局限了数字的范围为0-9,这里对数字的范围做了一般化,这样整个问题的难度就高了很多。

有两个需要注意的地方,在删除的时候不能直接下结论,删一个还是删两个需要再做判断;另一个是最后的拼接的比较函数要写好。

    public String Combine(List<Integer> a) {
        List<String> nums = new ArrayList<>();
        List<Integer> mod1 = new ArrayList<>();
        List<Integer> mod2 = new ArrayList<>();
        int sum = 0;
        for (int num : a) {
            String s = num + "";
            int curr = 0;
            for (int i = 0; i < s.length(); i++) curr += (s.charAt(i) - '0');
            sum += curr;
            nums.add(s);
            if (curr % 3 == 1) mod1.add(num);
            if (curr % 3 == 2) mod2.add(num);
        }
        Collections.sort(mod1);
        Collections.sort(mod2);
        if (sum % 3 == 1) {
            String f1 = "";
            String f2 = "";
            if (mod1.size() > 0) {
                List<String> rest = new ArrayList<>(nums);
                rest.remove(mod1.get(0) + "");
                Collections.sort(rest, (o1, o2) -> (o1 + o2).compareTo(o2 + o1));
                for (int i = rest.size() - 1; i >= 0; i--) f1 += rest.get(i);
            }
            if (mod2.size() > 1) {
                List<String> rest = new ArrayList<>(nums);
                rest.remove(mod2.get(0) + "");
                rest.remove(mod2.get(1) + "");
                Collections.sort(rest, (o1, o2) -> (o1 + o2).compareTo(o2 + o1));
                for (int i = rest.size() - 1; i >= 0; i--) f2 += rest.get(i);
            }
            if (f1.length() == 0) return f2;
            if (f2.length() == 0) return f1;
            return Long.valueOf(f1) >= Long.valueOf(f2) ? f1 : f2;
        }
        if (sum % 3 == 2) {
            String f1 = "";
            String f2 = "";
            if (mod2.size() > 0) {
                List<String> rest = new ArrayList<>(nums);
                rest.remove(mod2.get(0) + "");
                Collections.sort(rest, (o1, o2) -> (o1 + o2).compareTo(o2 + o1));
                for (int i = rest.size() - 1; i >= 0; i--) f1 += rest.get(i);
            }
            if (mod1.size() > 1) {
                List<String> rest = new ArrayList<>(nums);
                rest.remove(mod1.get(0) + "");
                rest.remove(mod1.get(1) + "");
                Collections.sort(rest, (o1, o2) -> (o1 + o2).compareTo(o2 + o1));
                for (int i = rest.size() - 1; i >= 0; i--) f2 += rest.get(i);
            }
            if (f1.length() == 0) return f2;
            if (f2.length() == 0) return f1;
            return Long.valueOf(f1) >= Long.valueOf(f2) ? f1 : f2;
        }
        String res = "";
        Collections.sort(nums, (o1, o2) -> (o1 + o2).compareTo(o2 + o1));
        for (int i = nums.size() - 1; i >= 0; i--) res += nums.get(i);
        return res;
    }

  

原文地址:https://www.cnblogs.com/hyserendipity/p/12867715.html