Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leetcode 2967. Minimum Cost to Make Array Equalindromic #303

Open
Woodyiiiiiii opened this issue Dec 23, 2023 · 0 comments
Open

Leetcode 2967. Minimum Cost to Make Array Equalindromic #303

Woodyiiiiiii opened this issue Dec 23, 2023 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

2967. Minimum Cost to Make Array Equalindromic

2967. Minimum Cost to Make Array Equalindromic
预处理回文数+中位数贪心(Python/Java/C++/Go)

这道题的思路如下:

  1. 首先要想到如何找到能够让数组变成最后满足条件的最小代价,抛开回文数的条件限制。在一个按序排序的数组中,显然位于最小数和最大数之间的数才能让代价最小,离最小数越小或者离最大数越大代价就越大,但如果只针对最小数和最大数,在这两个数之间的数的代价之和花费是相同的,所以可以不考虑这两个极数,缩小范围。最终,如果数组大小是奇数,离该数越近则代价越小;如果是偶数,则是两个数之间即可。也就是贪心,配合数学中位数
  2. 其次,要预处理所有的回文数,然后用二分找到满足上述代价最小的数。
class Solution {
    
    static List<Integer> palindromes = new ArrayList<>();
    static int N;

    static {
        for (int i = 1; i <= 9; i++) {
            palindromes.add(i);
        }
        for (int i = 2; i <= 9; i++) {
            for (int j = (int) Math.pow(10, i / 2 - 1); j < Math.pow(10, i / 2); j++) {
                String s = String.valueOf(j);
                StringBuilder sb = new StringBuilder(s);
                StringBuilder rv = new StringBuilder(sb);
                rv.reverse();
                if (i % 2 == 0) {
                    palindromes.add(Integer.parseInt(sb + rv.toString()));
                } else {
                    for (int k = 0; k <= 9; k++) {
                        palindromes.add(Integer.parseInt(sb.toString() + k + rv));
                    }
                }
            }
        }
        N = palindromes.size();
    }

    public long minimumCost(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);

        if (n % 2 != 0) {
            int mid = nums[n / 2];
            int low = low(mid), high = high(mid);
            return Math.min(cost(nums, low), cost(nums, high));
        } else {
            int mid1 = nums[n / 2], mid2 = nums[n / 2 - 1];
            int high1 = high(mid2);
            int low2 = low(mid1);
            return Math.min(cost(nums, low2), cost(nums, high1));
        }
    }

    private long cost(int[] nums, long x) {
        long res = 0;
        for (int num : nums) {
            res += Math.abs(x - num);
        }
        return res;
    }

    private int low(int x) {
        int l = 0, r = N;
        while (l < r) {
            int m = (l + r) >> 1;
            if (palindromes.get(m) > x) {
                r = m;
            } else {
                l = m + 1;
            }
        }
        return palindromes.get(l - 1);
    }

    private int high(int x) {
        int l = 0, r = N;
        while (l < r) {
            int m = (l + r) >> 1;
            if (palindromes.get(m) < x) {
                l = m + 1;
            } else {
                r = m;
            }
        }
        return l < N ? palindromes.get(l) : palindromes.get(l - 1);
    }
    
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant