IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> JAVA程序设计:从子集的和还原数组(LeetCode:1982) -> 正文阅读

[数据结构与算法]JAVA程序设计:从子集的和还原数组(LeetCode:1982)

存在一个未知数组需要你进行还原,给你一个整数 n 表示该数组的长度。另给你一个数组 sums ,由未知数组中全部 2n 个 子集的和 组成(子集中的元素没有特定的顺序)。

返回一个长度为 n 的数组 ans 表示还原得到的未知数组。如果存在 多种 答案,只需返回其中 任意一个 。

如果可以由数组 arr 删除部分元素(也可能不删除或全删除)得到数组 sub ,那么数组 sub 就是数组 arr 的一个 子集 。sub 的元素之和就是 arr 的一个 子集的和 。一个空数组的元素之和为 0 。

注意:生成的测试用例将保证至少存在一个正确答案。

示例 1:

输入:n = 3, sums = [-3,-2,-1,0,0,1,2,3]
输出:[1,2,-3]
解释:[1,2,-3] 能够满足给出的子集的和:
- []:和是 0
- [1]:和是 1
- [2]:和是 2
- [1,2]:和是 3
- [-3]:和是 -3
- [1,-3]:和是 -2
- [2,-3]:和是 -1
- [1,2,-3]:和是 0
注意,[1,2,-3] 的任何排列和 [-1,-2,3] 的任何排列都会被视作正确答案。
示例 2:

输入:n = 2, sums = [0,0,0,0]
输出:[0,0]
解释:唯一的正确答案是 [0,0] 。
示例 3:

输入:n = 4, sums = [0,0,5,5,4,-1,4,9,9,-1,4,3,4,8,3,8]
输出:[0,-1,4,5]
解释:[0,-1,4,5] 能够满足给出的子集的和。
?

提示:

1 <= n <= 15
sums.length == 2n
-104 <= sums[i] <= 104

参考:力扣

思路:本题来源于一个经典问题:已知子集的和求原子集并且已知原子集中所有的元素均为非负数。对于这个问题,我们很容易想到,将已知的子集的和从小到大排序,并且此时最小的值即为第一个元素,然后根据已知的元素,我们通过枚举子集的方式求出剩下的元素即可。

本题在原经典问题上进行了扩展,即原数组中存在负数,此时问题似乎变得难办了,我们应该考虑的是如何将该问题转化问原经典问题,使得问题得到解决。

为了满足原经典问题的约束条件,我们需要将保证原数组中所有负数组成的和,让其变为0,这样的话我们就能将子集的和转化为原数组中所有元素都为非负数时的和。这里读者可以思考一下。之后利用同样的解法即可。

class Solution {
    public int[] recoverArray(int n, int[] sums) {
        int mins = 0;
        for (int x : sums)
            mins = Math.min(mins, x);
        mins = -mins;
        Map<Integer, Integer> mp = new HashMap<>();
        Map<Integer, Boolean> mp1 = new HashMap<>();
        PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> a - b);
        for (int x : sums) {
            q.add(x + mins);
            mp.put(x + mins, mp.getOrDefault(x + mins, 0) + 1);
            mp1.put(x + mins, false);
        }
        mp.put(q.peek(), mp.get(q.peek()) - 1);
        q.poll(); //去掉空集合的值
        int[] ans = new int[n];
        ans[0] = q.poll();
        for (int i = 1; i < n; i++) {
            for (int msk = 0; msk < (1 << i); msk++) {
                if (((msk >> (i - 1) & 1)) != 0) {
                    int sm = 0;
                    for (int j = 0; j < i; j++) {
                        if ((msk >> j & 1) != 0)
                            sm += ans[j];
                    }
                    mp.put(sm, mp.getOrDefault(sm, 0) - 1);
                    if (mp.get(sm) <= 0)
                        mp1.put(sm, true);
                }
            }
            while (!q.isEmpty() && mp1.get(q.peek()))
                q.poll();
            ans[i] = q.peek();
        }
        for (int i = 0; i < (1 << n); i++) {
            int sm = 0;
            for (int j = 0; j < n; j++) {
                if ((i >> j & 1) != 0)
                    sm += ans[j];
            }
            if (sm == mins) {
                for (int j = 0; j < n; j++) {
                    if ((i >> j & 1) != 0)
                        ans[j] = -ans[j];
                }
                break;
            }
        }
        return ans;
    }
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:55:44  更:2021-09-22 14:56:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:50:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码