🚀 算法题 🚀 |
🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯
🚀 算法题 🚀 |
🚩 题目链接
⛲ 题目描述
给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
示例 1:
输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
输出: True
说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。
示例 2:
输入: nums = [1,2,3,4], k = 3
输出: false
提示:
1 <= k <= len(nums) <= 16
0 < nums[i] < 10000
每个元素的频率在 [1,4] 范围内
🌟 求解思路&实现代码&运行结果
⚡ 递归
🥦 求解思路
- 题目让我们求解是否可以将一个数组划分为k份相等的子集,可以通过递归求解。
- 首先求得数组总和,算一个分为k份每一个份的值,注意,如果不能整除,直接返回false。
- 然后设计递归函数,从index位置开始,选择了当前位置的数,得到nums[i] + cur,此时一共选择了cnt个子集,是否可以完成划分。
- 注意,这个递归函数的巧妙之处在于,如果此时cur == target,重新开始递归,此时cnt + 1。
- 有了基本的思路,接下来我们就来通过代码来实现一下的解法。
🥦 实现代码
class Solution {
public boolean canPartitionKSubsets(int[] nums, int k) {
int n = nums.length;
int sum = Arrays.stream(nums).sum();
Arrays.sort(nums);
if (sum % k != 0)
return false;
int target = sum / k;
boolean[] flag = new boolean[n];
return process(0, 0, 0, nums, target, k, flag);
}
public boolean process(int index, int sum, int cnt, int[] nums, int target, int k, boolean[] flag) {
if (cnt == k)
return true;
if (sum == target) {
return process(0, 0, cnt + 1, nums, target, k, flag);
}
for (int i = index; i < nums.length; i++) {
if (flag[i] || sum + nums[i] > target) {
continue;
}
flag[i] = true;
if (process(i + 1, sum + nums[i], cnt, nums, target, k, flag))
return true;
flag[i] = false;
}
return false;
}
}
🥦 运行结果
💬 共勉
最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |