作者: 负雪明烛
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. A Child's History of England.33

    To strengthen his power, the King with great ceremony betrothed his eldest daughter Matilda, then a ...

  2. Qt最好用评价最高的是哪个版本?

    来源: http://www.qtcn.org/bbs/read-htm-tid-89455.html /// Qt4:    4.8.7      4.X 系列终结版本 Qt5 :   5.6 LT ...

  3. Hive(八)【行转列、列转行】

    目录 一.行转列 相关函数 concat concat_ws collect_set collect_list 需求 需求分析 数据准备 写SQL 二.列转行 相关函数 split explode l ...

  4. 强化学习实战 | 表格型Q-Learning玩井字棋(二)

    在 强化学习实战 | 表格型Q-Learning玩井字棋(一)中,我们构建了以Game() 和 Agent() 类为基础的框架,本篇我们要让agent不断对弈,维护Q表格,提升棋力.那么我们先来盘算一 ...

  5. Linux lvm在线扩容

    1.查看磁盘空间 [root@bgd-mysql3 ~]# fdisk -l Disk /dev/sda: 107.4 GB, 107374182400 bytes, 209715200 sector ...

  6. Spring Boot 自动扫描组件

    使用@ComponentScan自动扫描组件 案例准备 1.创建一个配置类,在配置类上添加 @ComponentScan 注解.该注解默认会扫描该类所在的包下所有的配置类,相当于之前的 <con ...

  7. Ajax异步更新网页(使用原生JavaScript)

    一.页面代码 <!DOCTYPE html> <html> <head> <title>MyHtml.html</title> <me ...

  8. 【C/C++】习题3-7 DNA/算法竞赛入门经典/数组与字符串

    [题目] 输入m组n长的DNA序列,要求找出和其他Hamming距离最小的那个序列,求其与其他的Hamming距离总和. 如果有多个序列,求字典序最小的. [注]这道题是我理解错误,不是找出输入的序列 ...

  9. python初探——pandas使用

    一.简介 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pandas提供了大量 ...

  10. 基于Web的质量和测试度量指标

    直观了解软件质量和测试的完整性 VectorCAST/Analytics可提供便于用户理解的web仪表盘视图来显示软件代码质量和测试完整性指标,让用户能够掌握单个代码库的趋势,或对比多个代码库的度量指 ...