当前位置:网站首页>698. Divided into k equal subsets ●●
698. Divided into k equal subsets ●●
2022-07-05 23:24:00 【chenyfan_】
698. Divided into k Equal subsets ●●
describe
Given an array of integers nums And a positive integer k, find whether Divide this array into k A non empty subset , Its The sum is equal .
Example
Input : nums = [4, 3, 2, 3, 5, 2, 1], k = 4
Output : True
explain : It is possible to divide it into 4 A subset of (5),(1,4),(2,3),(2,3) Equal to the sum .
Answer key
First, the problem is abstracted : Yes n A ball ,k A barrel , How to allocate the balls into the bucket so that the sum of the balls in each bucket is target. As shown in the figure below :
1. to flash back , The ball ( Numbers ) visual angle
From the perspective of the ball , Each ball needs to make three choices , namely : Choose to put 1 Bucket number 、2 Bucket number 、3 Bucket number . All the balls need do k n k^n kn Secondary selection .
Because backtracking is an idea of violent solution , So there are three choices for each ball , Only after the selection is performed can we know whether the selection is the optimal solution . To put it bluntly, it is to implement these three options in turn , If the selection is found to be non optimal after recursion to the following , Then start backtracking , Make other choices , Until all choices are traversed .
Pruning operations are critical .
class Solution {
public:
bool backtrack(int idx, vector<int>& nums, vector<int>& buckets, int target, int k){
if(idx == nums.size()) return true; // The end condition : All elements are divided into buckets , At this time, the sum of each set must be equal
for(int i = 0; i < k; ++i){
if (i > 0 && idx == 0) break ; // The first element is the same in which bucket , So it fails to trace back to the first element ( prune )
if(buckets[i] + nums[idx] > target) continue; // prune , The sum of sets cannot be greater than target
if(i > 0 && buckets[i] == buckets[i-1]) continue; // prune , The selection of the same set and can be seen as a repetition
buckets[i] += nums[idx]; // Join the collection i
if(backtrack(idx+1, nums, buckets, target, k)) return true; // recursive
buckets[i] -= nums[idx]; // to flash back
}
return false; // k None of the barrels meet the requirements
}
bool canPartitionKSubsets(vector<int>& nums, int k) {
int sum = 0, maxNum = 0;
for(int num : nums){
sum += num;
if(maxNum < num) maxNum = num;
}
if(maxNum*k > sum || sum % k != 0) return false; // prune
int target = sum / k; // Target set and
vector<int> buckets(k, 0); // Bucket collection
sort(nums.begin(), nums.end(), greater<int>()); // Descending , Fill in from big to small , Reduce the consumption of backtracking
return backtrack(0, nums, buckets, target, k);
}
};
2. to flash back , bucket ( aggregate ) visual angle
From the perspective of the bucket , Each bucket requires six choices , namely : Whether to choose 1 Put the ball in 、 Whether to choose 2 Put the ball in 、…、 Whether to choose 6 Put the ball in . All barrels need do k 2 n k2^n k2n Secondary selection .
The following is 「 Bucket Perspective 」 Decision tree under
First, explain the decision tree , The first i Layer for j No. barrel makes No x Secondary selection , Choices to make : Whether to choose 1 ~ 6 Ball No , until k End after all barrels are full ;
because , Each ball can only be selected by one bucket , So when a ball is selected by a bucket , The other bucket cannot choose the ball , See the branch marked in red in the following figure ;
The condition for judging whether a ball can be selected is :(1) Whether the ball has been selected ? (2) After putting the ball , Whether the bucket overflows ?
When the array is ordered , The choice of excluding the next case with the same value as the current one is crucial to reduce the time complexity .
class Solution {
public:
unordered_set<vector<bool>> hash;
bool backtrack(int start, vector<int>& nums, vector<bool>& used, vector<int>& buckets, int target, int k){
if(k == 0) return true; // The end condition : All barrels are full of elements
if(buckets[k-1] == target) return backtrack(0, nums, used, buckets, target, k-1); // The current barrel is full , Start loading the next bucket
for(int i = start; i < nums.size(); ++i){
// Traverse each ball , Choose whether to load
if(used[i] == true) continue; // The ball has been used
if(buckets[k-1] + nums[i] > target) continue; // prune , The sum of sets cannot be greater than target
used[i] = true; // Select the ball and add it to the bucket
buckets[k-1] += nums[i];
if(backtrack(i+1, nums, used, buckets, target, k)) return true; // recursive , Start with the next ball
buckets[k-1] -= nums[i]; // to flash back
used[i] = false;
while (i + 1 < nums.size() && nums[i + 1] == nums[i]) ++i; // prune , In order , If the next one is the same as the current one, it will definitely not work
}
return false; // All the balls cannot meet the conditions
}
bool canPartitionKSubsets(vector<int>& nums, int k) {
int sum = 0, maxNum = 0;
for(int num : nums){
sum += num;
if(maxNum < num) maxNum = num;
}
if(maxNum*k > sum || sum % k != 0) return false; // prune
int target = sum / k; // Target set and
vector<int> buckets(k, 0); // Bucket collection
vector<bool> used(nums.size(), false); // Use the tag
sort(nums.begin(), nums.end()); // Sort
return backtrack(0, nums, used, buckets, target, k);
}
};
- The maximum array size is 16 individual , therefore bool The form of array tags can be optimized by using bit operation tags
int used = 0;
initialization (used >> i) & 1 == 1
Judgment No. i Whether the number has been used used |= 1 << i;
Mark the i Number used ^= 1 << i;
The first i Number unmarked
边栏推荐
- Initial experience | purchase and activate typora software
- Negative sampling
- Thoroughly understand JVM class loading subsystem
- Three. JS VR house viewing
- Use of metadata in golang grpc
- leecode-学习笔记
- JVM的简介
- 3D reconstruction of point cloud
- LabVIEW打开PNG 图像正常而 Photoshop打开得到全黑的图像
- Development specification: interface unified return value format [resend]
猜你喜欢
Basic knowledge of database (interview)
PLC编程基础之数据类型、变量声明、全局变量和I/O映射(CODESYS篇 )
Matlab smooth curve connection scatter diagram
From the perspective of quantitative genetics, why do you get the bride price when you get married
LabVIEW打开PNG 图像正常而 Photoshop打开得到全黑的图像
Commonly used probability distributions: Bernoulli distribution, binomial distribution, polynomial distribution, Gaussian distribution, exponential distribution, Laplace distribution and Dirac delta d
Technical specifications and model selection guidelines for TVs tubes and ESD tubes - recommended by jialichuang
3: Chapter 1: understanding JVM specification 2: JVM specification, introduction;
Getting started stm32--gpio (running lantern) (nanny level)
Data type, variable declaration, global variable and i/o mapping of PLC programming basis (CoDeSys)
随机推荐
3D point cloud slam
Basic knowledge of database (interview)
UART Application Design and Simulation Verification 2 - TX Module Design (Stateless machine)
npm ELECTRON_ Mirror is set as domestic source (npmmirror China mirror)
JVM的简介
视频标准二三事
3:第一章:认识JVM规范2:JVM规范,简介;
Neural structured learning - Part 2: training with natural graphs
Matlab smooth curve connection scatter diagram
Déterminer si un arbre binaire est un arbre binaire complet
(4)UART應用設計及仿真驗證2 —— TX模塊設計(無狀態機)
派对的最大快乐值
Use of grpc interceptor
Calculating the number of daffodils in C language
The maximum happiness of the party
LeetCode——Add Binary
Initial experience | purchase and activate typora software
Introduction to JVM
Simple and beautiful method of PPT color matching
Solution to the packaging problem of asyncsocket long connecting rod