【Leetcode】2035. Partition Array Into Two Arrays to Minimize Sum Difference

题目地址:

https://leetcode.com/problems/partition-array-into-two-arrays-to-minimize-sum-difference/description/

给定一个长 2 n 2n 2n的数组 A A A,要求将其分为两部分,使得两部分各自和作差的绝对值最小,返回这个最小的绝对值。

先开个哈希表 m m m A A A的后 n n n个数字的所有组合的和,key是数字个数,value是和的所有可能性,然后再暴力枚举前 n n n个数字的所有组合,如果这个组合含 c c c个数字,那么后 n n n个数,就要取 n − c n-c nc个数字,为了二分方便,哈希表的value用set来存;如果前 n n n个数字的某个组合的和是 s s s,那么我们就要求 m [ n − c ] m[n-c] m[nc]里与 s s s求和之后离 ∑ A / 2 \sum A/2 A/2最近的数,这个可以用lower_bound来做。代码如下:

class Solution {
 public:
  int minimumDifference(vector<int> &a) {
    int n = a.size() / 2, res = INT_MAX;
    unordered_map<int, set<long>> mp;
    dfs(n, 0, 0, a, mp);
    long sum = 0;
    for (int x : a) sum += x;
    for (int i = 0; i < 1 << n; i++) {
      int cnt = 0;
      long s = 0;
      for (int k = 0, t = i; t; k++) {
        if (t & 1) {
          s += a[k];
          cnt++;
        }
        t >>= 1;
      }
      auto &st = mp[n - cnt];
      auto it = st.lower_bound(sum / 2 - s);
      if (it != st.end()) res = min(res, (int)abs(sum - 2 * (*it + s)));
      if (it != st.begin()) res = min(res, (int)abs(sum - 2 * (*(--it) + s)));
    }

    return res;
  }

  void dfs(int u, int cnt, int sum, vector<int> &a,
           unordered_map<int, set<long>> &mp) {
    mp[cnt].insert(sum);
    for (int i = u; i < a.size(); i++) dfs(i + 1, cnt + 1, sum + a[i], a, mp);
  }
};

时间复杂度 O ( 2 n log ⁡ n ) O(2^n\log n) O(2nlogn),空间 O ( 2 n ) O(2^n) O(2n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值