【LeetCode】698. Partition to K Equal Sum Subsets 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/
题目描述
Given an array of integers nums and a positive integer k, find whether it’s possible to divide this array into k non-empty subsets whose sums are all equal.
Example 1:
Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
Output: True
Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.
Note:
- 1 <= k <= len(nums) <= 16.
- 0 < nums[i] < 10000.
题目大意
判断一个数组是否可以分成k组,每组的和相等。
解题方法
回溯法
这是一个套题,和416. Partition Equal Subset Sum,473. Matchsticks to Square基本一致的代码,上面的两个题分别是求平分成2份和4份。这个是任意的k份。所以改成了k组数字记录的div,最后看是否能够正好进行平分。
直接使用回溯法即可,这个回溯的要求是恰好把nums的所有数字用过一遍,使得目标数组中恰好有k个相同数字。当所有的数字恰好用完的时候,就是我们平分的时候,即可返回true。题目给出的数字范围只到16,所以本算法时间复杂度是O(N!),仍然能通过。
这里要证明,为什么只需要判断恰好用完即可返回true。因为我们所有数字的和是确定的,即sum(target) = div * k = sum(nums)。如果我们在每个位置放数字的时候,保证了放置的数字<=该位置的数字,即保证了在最终状态的target[i]>=0。此时有sum(target) >= 0。又已知所有数字恰好用完,所以恰好有sum(target) = 0。故,当所有数字恰好用完时,target的每个位置都是0.
Python代码:
class Solution:
def canPartitionKSubsets(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
if not nums or len(nums) < k: return False
_sum = sum(nums)
div, mod = divmod(_sum, k)
if _sum % k or max(nums) > _sum / k: return False
nums.sort(reverse = True)
target = [div] * k
return self.dfs(nums, k, 0, target)
def dfs(self, nums, k, index, target):
if index == len(nums): return True
num = nums[index]
for i in range(k):
if target[i] >= num:
target[i] -= num
if self.dfs(nums, k, index + 1, target): return True
target[i] += num
return False
C++代码如下:
class Solution {
public:
bool canPartitionKSubsets(vector<int>& nums, int k) {
if (nums.size() < k) return false;
int sum = accumulate(nums.begin(), nums.end(), 0);
if (sum % k != 0) return false;
vector<int> target(k, sum / k);
return helper(nums, 0, target);
}
bool helper(vector<int>& nums, int index, vector<int>& target) {
if (index == nums.size()) return true;
int num = nums[index];
for (int i = 0; i < target.size(); ++i) {
if (target[i] >= num) {
target[i] -= num;
if (helper(nums, index + 1, target))
return true;
target[i] += num;
}
}
return false;
}
};
另外一种Python解法定义的dfs()函数的意义是使用nums[ind:]能不能构成k个和分别为self.target的数字,因为这种做法会反复遍历nums,而不像上面这种做法只用遍历一次,所以这个做法需要用visited数组,表示nums[i]数字是否已经使用过。
class Solution(object):
def canPartitionKSubsets(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
if k == 1: return True
self.n = len(nums)
if self.n < k: return False
total = sum(nums)
if total % k: return False
self.target = total / k
visited = [0] * self.n
nums.sort(reverse = True)
def dfs(k, ind, sum, cnt):
if k == 1: return True
if sum == self.target and cnt > 0:
return dfs(k - 1, 0, 0, 0)
for i in range(ind, self.n):
if not visited[i] and sum + nums[i] <= self.target:
visited[i] = 1
if dfs(k, i + 1, sum + nums[i], cnt + 1):
return True
visited[i] = 0
return False
return dfs(k, 0, 0, 0)
日期
2018 年 4 月 2 日 —— 要开始准备ACM了
2019 年 2 月 24 日 —— 周末又结束了
【LeetCode】698. Partition to K Equal Sum Subsets 解题报告(Python & C++)的更多相关文章
- [LeetCode] 698. Partition to K Equal Sum Subsets
Problem Given an array of integers nums and a positive integer k, find whether it's possible to divi ...
- 【leetcode】698. Partition to K Equal Sum Subsets
题目如下: 解题思路:本题是[leetcode]473. Matchsticks to Square的姊妹篇,唯一的区别是[leetcode]473. Matchsticks to Square指定了 ...
- 698. Partition to K Equal Sum Subsets
Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...
- 698. Partition to K Equal Sum Subsets 数组分成和相同的k组
[抄题]: Given an array of integers nums and a positive integer k, find whether it's possible to divide ...
- [LeetCode] Partition to K Equal Sum Subsets 分割K个等和的子集
Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...
- LeetCode Partition to K Equal Sum Subsets
原题链接在这里:https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/ 题目: Given an arr ...
- Partition to K Equal Sum Subsets
Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...
- [Swift]LeetCode698. 划分为k个相等的子集 | Partition to K Equal Sum Subsets
Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...
- 【LeetCode】364. Nested List Weight Sum II 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...
随机推荐
- linux中chage命令的基本使用
在Linux中chage命令常用于设置系统用户的账户属性 Usage: chage [options] LOGIN Options: -d, --lastday LAST_DAY set date o ...
- mysql 分组统计、排序、取前N条记录解决方案
需要在mysql中解决记录的分组统计.排序,并抽取前10条记录的功能.现已解决,解决方案如下: 1)表结构 CREATE TABLE `policy_keywords_rel` ( `id` int( ...
- C/C++ Qt 数据库QSql增删改查组件应用
Qt SQL模块是Qt中用来操作数据库的类,该类封装了各种SQL数据库接口,可以很方便的链接并使用,数据的获取也使用了典型的Model/View结构,通过MV结构映射我们可以实现数据与通用组件的灵活绑 ...
- A Child's History of England.28
By such means, and by taxing and oppressing the English people in every possible way, the Red King b ...
- acknowledge
accord+knowledge. accord好几个意思,knowledge不遑多让,We gotta acknowledge the word acknowledge has many meani ...
- day11 序列化组件、批量出入、自定义分页器
day11 序列化组件.批量出入.自定义分页器 今日内容详细 ajax实现删除二次提醒(普通版本) ajax结合第三方插件sweetalert实现二次提醒(样式好看些) ajax如何发送文件数据 aj ...
- SparkStreaming消费Kafka,手动维护Offset到Mysql
目录 说明 整体逻辑 offset建表语句 代码实现 说明 当前处理只实现手动维护offset到mysql,只能保证数据不丢失,可能会重复 要想实现精准一次性,还需要将数据提交和offset提交维护在 ...
- HTTP请求 Java API
1.导入依赖 <dependency> <groupId>commons-httpclient</groupId> <artifactId>common ...
- IDEA2021.2安装与配置
https://blog.csdn.net/qq_37242720/article/details/119349394
- JavaIO——File类
1.File文件类 File类(描述具体文件或文件夹的类):是唯一一个与文件本身操作有关的程序类,可完成文件的创建.删除.取得文件信息等操作.但不能对文件的内容进行修改. (1)File类的基本使用 ...