作者: 负雪明烛
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. 1 <= k <= len(nums) <= 16.
  2. 0 < nums[i] < 10000.

题目大意

判断一个数组是否可以分成k组,每组的和相等。

解题方法

回溯法

这是一个套题,和416. Partition Equal Subset Sum473. 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++)的更多相关文章

  1. [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 ...

  2. 【leetcode】698. Partition to K Equal Sum Subsets

    题目如下: 解题思路:本题是[leetcode]473. Matchsticks to Square的姊妹篇,唯一的区别是[leetcode]473. Matchsticks to Square指定了 ...

  3. 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 ...

  4. 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 ...

  5. [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 ...

  6. LeetCode Partition to K Equal Sum Subsets

    原题链接在这里:https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/ 题目: Given an arr ...

  7. 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 ...

  8. [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 ...

  9. 【LeetCode】364. Nested List Weight Sum II 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...

随机推荐

  1. adblock plus-看下图你就懂

  2. 学习java的第二十一天

    一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...

  3. 数据集成工具—FlinkX

    @ 目录 FlinkX的安装与简单使用 FlinkX的安装 FlinkX的简单使用 读取mysql中student表中数据 FlinkX本地运行 MySQLToHDFS MySQLToHive MyS ...

  4. 日常Java 2021/10/11

    抽象类 所有对象都是通过类描述的,但不是所有的类都是用来描述对象,就好比抽象类,此类中没有足够的信息描述一个对象. 抽象类不能实例化对象,所以抽象类必须的继承,才可以使用. 抽象方法 Abstract ...

  5. 学习java 7.10

    学习内容: List 集合:有序集合,用户可以精确控制列表中每个元素的插入位置 List 集合特点:有序:存储和取出的元素顺序一致 可重复:存储的元素可以重复 增强for循环:简化数组和 Collec ...

  6. web必知,多终端适配

    导读 移动端适配,是我们在开发中经常会遇到的,这里面可能会遇到非常多的问题: 1px问题 UI图完美适配方案 iPhoneX适配方案 横屏适配 高清屏图片模糊问题 ... 上面这些问题可能我们在开发中 ...

  7. 【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(一)-初步认识SD卡

    由于一张SD卡要能读写,涉及到的技术有些多,我打算分以下几篇博客 [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(一)-初步认识SD卡 [STM32]使用SDIO进行SD卡读写,包含 ...

  8. nexus 私服 拉不了 jar 包,报 Not authorized

    问题: 无法下载导入jar包,idea reload 时 报: Could not transfer artifact com.xxx:parent:pom:1.0-SNAPSHOT from/to ...

  9. 一行配置搞定 Spring Boot项目的 log4j2 核弹漏洞!

    相信昨天,很多小伙伴都因为Log4j2的史诗级漏洞忙翻了吧? 看到群里还有小伙伴说公司里还特别建了800+人的群在处理... 好在很快就有了缓解措施和解决方案.同时,log4j2官方也是速度影响发布了 ...

  10. Markdown随时记录

    Markdown学习 推荐文本编译器 Typora 标题(支持六级) 一级标题:# + 空格 + 内容 二级标题:## + 空格 + 内容 三级标题:### + 空格 + 内容 . . . 字体 粗体 ...