zoukankan      html  css  js  c++  java
  • 416. Partition Equal Subset Sum

    问题描述:

    Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

    Note:

    1. Each of the array element will not exceed 100.
    2. The array size will not exceed 200.

    Example 1:

    Input: [1, 5, 11, 5]
    
    Output: true
    
    Explanation: The array can be partitioned as [1, 5, 5] and [11].
    

    Example 2:

    Input: [1, 2, 3, 5]
    
    Output: false
    
    Explanation: The array cannot be partitioned into equal sum subsets.

    解题思路:

    首先我们可以对数组求和,求和后判断能否被2整除,如果不能被二整除,那么绝对不可能分成两个集合且每个集合的和相等。

    若可以被二整除,我们进一步讨论是否有这样的集合存在。 target = sum>>2

    一开始我想用DFS来做这道题,就是找数组中是否有数字的和为target。

    过不了OJ( ・᷄ὢ・᷅ )

    朋友们,每当这时候,我们要想想,能不能用DP做呀?

    dp[i]代表数组中是否存在集合使得和为i。

    对数组nums中每一个数字num:

      dp[i] = dp[i] || dp[i - num]

    那i如何取值呢?

    因为我们想要返回的是dp[target]

    所以可以令 i = target。

    此时含义为,num和其之前的数字能够组成和为target的集合吗?

    变换方式为i--,直至i == num(为了避免出现负数)

    还有位操作的方法:参考GrandYang 

    重点:把bits向左平移num位,然后再或上原来的bits,这样所有的可能出现的和位置上都为1

    代码:

    class Solution {
    public:
        bool canPartition(vector<int>& nums) {
            int sum = accumulate(nums.begin(), nums.end(), 0), target = sum >> 1;
            if (sum & 1) return false;
            vector<int> dp(target + 1, 0);
            dp[0] = 1;
            for(auto num : nums) 
                for(int i = target; i >= num; i--)
                    dp[i] = dp[i] || dp[i - num];
            return dp[target];
        }
    
    };

    参考链接:Concise C++ Solution summary with DFS, DP, BIT

  • 相关阅读:
    详解Windows注册表分析取证
    逻辑漏洞简单的分析
    文件解析漏洞汇总
    aspcms 这个靶场。。。
    WebBug靶场基础篇 — 03
    WebBug靶场基础篇 — 02
    WebBug靶场介绍篇 — 01
    漏洞挖掘中的常见的源码泄露
    PHP对象Object的概念
    从史上八大MySQL事故中学到的经验
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9219567.html
Copyright © 2011-2022 走看看