【经典题目分析】数组分割问题

news/2024/7/20 21:55:50 标签: 深度优先, 算法, 图论

文章目录

  • 698. 划分为k个相等的子集
  • 416. 分割等和数组

698. 划分为k个相等的子集

在这里插入图片描述

把一个数组,拆分成K个大小一样的子数组。方法可以是状态枚举,或者dfs

class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) {
    // 从大向小,提高效率
        sort(nums.begin(), nums.end(),greater<int>());
        int total = accumulate(nums.begin(), nums.end(), 0);
        if (total%k != 0) {
            return false;
        } 
        int avg = total/k;
        if (nums.front()>avg) return false;
        int n = nums.size();
        vector<int> sum(k,0);
        // 使用dfs的方法,每次去枚举每一个队列里能不能有空间放开这个数字
        function<bool(int)> dfs = [&](int x){
            if(x == n) return true;
            int cur = nums[x];
            for (int i = 0;i<k;i++){
                if(i!= 0 && sum[i] == sum[i-1]) continue; // 这个执行了一个剪枝,如果前一个状态和当前一样,就不需要考虑了。
                sum[i] += cur;
                if(sum[i]<=avg && dfs(x+1)){
                    return true;
                }
                sum[i] -= cur;
            }
            return false;
        };
        
        return dfs(0);
    }
};

状态压缩的方法

class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int total = accumulate(nums.begin(), nums.end(), 0);
        if (total%k != 0) {
            return false;
        } 
        int avg = total/k;
        if (nums.back()>avg) return false;
        int n = nums.size();
        int size = 1<<n;
        vector<int> dp(size, -1);
        dp[0] = 0;
        for(int i = 0;i<size;i++){          
            if(dp[i] == -1) continue;
            for (int j = 0;j<n;j++){
                if(dp[i] + nums[j] > avg) break;
                if(((1<<j) & i) == 0){
                    int next = i+ (1<<j);
                    if(dp[next] != -1) continue;         
                    dp[next] = (dp[i]+nums[j])% avg ;
                }
                if(dp[size-1] == 0) return true; 
            }
        }
        return false;
    }
};

416. 分割等和数组

在这里插入图片描述

这个问题其实可以被看做是上一个问题的子问题,但是也可以被简化为其中一个数组能够正好凑到target。因此问题可以被化简为背包问题求解。

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = 0;
        int maxnum = 0;
        for (auto x: nums){
            sum += x;
            maxnum = max(maxnum, x);
        }
        if(sum%2!=0) return false;
        int target = sum/2;
        if (maxnum>target) return false;
        int n = nums.size();
        if (n < 2) {
            return false;
        }
        vector<bool> dp(target+1, false);
        dp[0] = true;
        for (int i = 0;i<n;i++){
            int cur = nums[i];
            for (int j = target;j>=cur;j--){
                dp[j] = dp[j] || dp[j-cur];
            }
        }
        return dp[target];
    }
};

http://www.niftyadmin.cn/n/1694876.html

相关文章

VS连接MySQL数据库

C连接MySQL数据库有两种方式&#xff1a; <br>1、通过MySQL 的C API&#xff08;决定使用这种方式&#xff09; 也可以使用MySQL 。 [Mysql是官方发布的、一个为MySQL设计的C语言的API。Mysql为Mysql的C-Api的再次封装&#xff0c;它用STL(Standard Template Language)开…

hadoop 报错 org.apache.hadoop.mapred.TaskTracker: Process Thread Dump: lost task

项目最近报错&#xff0c;形如&#xff1a; org.apache.hadoop.mapred.TaskTracker: Process Thread Dump: lost task Thread 2958 (process reaper):State: RUNNABLEBlocked count: 0Waited count: 0Stack:java.lang.UNIXProcess.waitForProcessExit(Native Method)java.lang.…

eclipse中设置.class文件的输出路径及“java build path”的设置

1.设置"source folder"与"output folder".* source folder:存放.java源文件的根目录;* output folder&#xff1a;.class编译输出的根目录&#xff1b;* 纯“java project”中&#xff0c;一般把"src"设置为source folder&#xff0c;把bin设置为…

[LeetCode] Same Tree 判断相同树

Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 判断两棵树是否相同和之前的判断两棵树是否对称都是一样的原理&#xff0c;利…

Linq to SQL - 撤销所有未提交的改动

在某些情况下我们需要撤销/丢弃所有未提交的改动&#xff0c;包括Update, Delete和Insert。context中GetChangeSet()方法可以返回当前所有未提交的改动&#xff0c;而我们的目标是清空Change Set。 撤销Update很简单&#xff0c;通过OverwriteCurrentValues的模式刷新&#xff…

面向对象的Javascript - 通过原型(Prototype)实现继承

Prototype的使用方式 Prototype(原型)是Javascript中实现对象继承的基础方式&#xff0c;使用方式为 [function].prototype [object1] [function]可认为相当于type/class&#xff0c;这样可以使该类型的所有对象继承[object1]中所有Public的属性和方法。在这里public的意思是使…

CentOS7修改网卡为eth0

CentOS7修改网卡为eth0 1.编辑网卡信息[rootlinux-node2~]# cd /etc/sysconfig/network-scripts/ #进入网卡目录 [rootlinux-node2network-scripts]# mv ifcfg-eno16777728 ifcfg-eth0 #重命名网卡名称 [rootlinux-node2 network-scripts]# cat ifcfg-eth0 #编辑网卡信息 TY…

三种进程和线程数据共享模块方法Queue》Pipe》manager

》》》》线程中的queue import threading import queue def f(qq):print("in child",qq.qsize())#打印父进程中q扥数据个数qq.put([42,None,hellow])#往父进程中的q增减新的数据if __name__ __main__:q queue.Queue()#父进程生成一个qq.put(test123)#往父进程中增加…