作者: 负雪明烛
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. Deep Learning(深度学习)整理,RNN,CNN,BP

     申明:本文非笔者原创,原文转载自:http://www.sigvc.org/bbs/thread-2187-1-3.html 4.2.初级(浅层)特征表示 既然像素级的特征表示方法没有作用,那怎 ...

  2. mysql 实现某年单季度内的品牌TOPn销量在此年此单季度内销量占比

    数据表:       结果表: mysql语句:  

  3. 『学了就忘』Linux文件系统管理 — 62、手动分配swap分区

    目录 1.查看swap分区情况 2.手动修改swap分区 3.格式化swap分区 4.使用swap分区 5.配置swap分区开机之后自动挂载 1.查看swap分区情况 swap分区就相当于是内存的一个 ...

  4. 表格合并单元格【c#】

    gridBranchInfo.DataSource = dtBranchViewList; gridBranchInfo.DataBind(); Random random = new Random( ...

  5. jsp的动态包含和静态包含

    jsp的动态包含和静态包含 例如:提取一个公共的页面(top.jsp)到/WEB-INF/jsp/common/目录下 动态包含: 被包含的页面也会独立编译,生成字节码文件,一般包含页面信息频繁变化的 ...

  6. 【讨论】APP的免填邀请码解决方案

    00x0 具体需求 app中已注册的用户分享一个含有邀请码的二维码,分享到朋友圈新用户在朋友圈打开这个这个链接下载app.新用户安装后打开app后就自动绑定邀请码要求用户不填写任何东西 朋友老板出差给 ...

  7. stm32串行设备接口SPI控制max31865

    本人是刚入行的嵌入式,之前也没有多少项目经验,故在公司的这几个月里,可谓是如履薄冰,对于公司不同项目使用的不同的设备之多,数据手册之繁杂,让我不禁望洋兴叹,故而不愿意放弃周末这大好的自我提升时间,努力 ...

  8. 转 Android Lifecycle、ViewModel和LiveData

    转自:https://www.jianshu.com/p/982545e01d0a 1.概述 在I / O '17的时候,其中一个重要的主题是Architecture Components.这是一个官 ...

  9. Shell脚本实现根据文件的修改时间来分类文件

    #!/bin/bash # exctute # ./mod.sh file_type input_folder output_folder # ./mod.sh *.txt /tmp /data/ # ...

  10. 【Java 调优】Java性能优化

    Java性能优化的50个细节(珍藏版) 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: ...