805. Split Array With Same Avera

2018-06-12  本文已影响0人  Nancyberry

Description

In a given integer array A, we must move every element of A to either list B or list C. (B and C initially start empty.)

Return true if and only if after such a move, it is possible that the average value of B is equal to the average value of C, and B and C are both non-empty.

Example :
Input:
[1,2,3,4,5,6,7,8]
Output: true
Explanation: We can split the array into [1,4,5,8] and [2,3,6,7], and both of them have the average of 4.5.

Note:

Solution

HashMap + DP (TLE)

类似01背包问题,注意从后向前遍历!

class Solution {
    public boolean splitArraySameAverage(int[] arr) {
        int n = arr.length;
        int totalSum = getSum(arr);
        
        Map<Integer, Set<Integer>> sum2Count = new HashMap<>();
        Set<Integer> initial = new HashSet<>();
        initial.add(0);
        sum2Count.put(0, initial);
        
        for (int i = 0; i < n; ++i) {
            for (int sum = totalSum; sum >= arr[i]; --sum) {    // back to front!
                if (!sum2Count.containsKey(sum - arr[i])) {
                    continue;
                }
                
                if (!sum2Count.containsKey(sum)) {
                    sum2Count.put(sum, new HashSet<>());
                }
                Set<Integer> tmp = new HashSet<>(); // add to tmp to avoid ConcurrentModityException

                for (int count : sum2Count.get(sum - arr[i])) {
                    if (count + 1 != n) {
                        tmp.add(count + 1);
                    }
                }
                
                sum2Count.get(sum).addAll(tmp);
                for (int count : sum2Count.get(sum)) {
                    if (isAvgEqual(sum, count, totalSum, n)) {
                        System.out.println(sum2Count.entrySet());
                        System.out.println(sum + "/" + count + " and " + totalSum + "/" + n);
                        return true;
                    }
                }
            }
        }
        
        return false;
    }
    // both of the count should larger than 0!
    private boolean isAvgEqual(int sum1, int count1, int sum2, int count2) {
        return count1 > 0 && count2 > 0 && count1 * sum2 == count2 * sum1;
    }
    
    private int getSum(int[] arr) {
        int sum = 0;
        for (int v : arr) {
            sum += v;
        }
        return sum;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读