Leetcode:805 Split Array With Same Average

Description

You are given an integer array nums.

You should move each element of nums into one of the two arrays A and B such that A and B are non-empty, and average(A) == average(B).

Return true if it is possible to achieve that and false otherwise.

Note that for an array arr, average(arr) is the sum of all the elements of arr over the length of arr.

Example

Input: nums = [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 an average of 4.5.

分析

这道题目有点难,因为长度为 N 的数组它的组合有 2**N 种。
题目给出数字范围 N < 30 且每个数均小于 104。
30 * 104 约等于 3200,只需要求 dp[使用的数字个数][数字和] 即可
此外,本地和在一个数组中找出和等于某个数的方法有点类似

实现

class Solution(object):
    def splitArraySameAverage(self, nums):        
        N, S = len(nums), sum(nums)
        H = N //2 + 1
        if 2 > N:
            return False
        if N == 2:
            return nums[0] == nums[1]
        
        divid = False

        for i in range(1, H):  ## 这里是优化速度的,速度速度从 1348 ms 提升到 80 ms
            if S * i % N == 0:
                divid = True
                break
            
        if not divid:
            return False
        
        dp =  [[{} for _ in range(H)] for _ in range(2)]
        dp[1][1][nums[0]] = 1
        dp[1][0][0] = 1
        
        for i in range(2, N+1):

            now_level, pre_level = i % 2, (i-1) % 2
            dp[now_level] = [{} for _ in range(H)]

            for used in range(H):
                dp[now_level][used].update(dp[pre_level][used])
                for j in dp[pre_level][used]:
                    n_j = j+nums[i-1]
                    if N * n_j == (used+1)*S :
                        return True
                    if H > used+1:
                        dp[now_level][used+1][n_j] = 1

        return False

总结

提交很多次,大部分是 index out 导致的 runtime error。部分是 TLE 
第一次通过的版本速度有点慢,只 beat 25% 的提交。优化后的速度 beat 75 % 的速度
posted @ 2021-08-20 19:47  tmortred  阅读(30)  评论(0编辑  收藏  举报