首页 > 试题广场 >

数组分解K个等和子数组

[编程题]数组分解K个等和子数组
  • 热度指数:460 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

给一个整数数组num,和一个正整数k,能否把数组num 切成k个子集,且各个子集的和相等。

请写出代码,返回bool 类型


输入描述:
一个整数数组num,和一个正整数k


输出描述:
返回true 或者 false ,bool类型
示例1

输入

[4, 3, 2, 3, 5, 2, 1];4

输出

True

说明

可以分解为四个,他们之和都是5: (5), (1, 4), (2,3), (2,3)
这题解析是不是完全错误啊
发表于 2022-12-14 23:29:58 回复(0)
#include <iostream>
#include <vector>
#include <math.h>
#include <string>
#include <sstream>
#include <algorithm>

using namespace std;

vector<bool> tri;
vector<int> number;
int K;
bool result=false;

//des 目标值   countK 当前值
void dfs(int index,int des,int countI,int countD){
    
    if(countD==des){
        countI++;
        if(countI==K){
            result=true;
            return;
        }
        int nindex=-1;
        for(int i=0;i<tri.size();i++){
            if(!tri[i]){
                nindex=i;
                break;
            }
        }
        if(nindex==-1)
            return ;
        tri[nindex]=1;
        dfs(nindex,des,countI,number[nindex]);
        tri[nindex]=0;
    }
    if(countD<des&&index<number.size()&&!tri[index+1]){
        tri[index+1]=1;
        //选择index+1
        dfs(index+1,des,countI,countD+number[index+1]);
        tri[index+1]=0;
        
        //未选择index+1
        dfs(index+1,des,countI,countD);
    }
}

void funS(string s){
    istringstream is(s);
    char ts;
    int ti;
    while (is>>ts) {
        if (ts==']') {
            is>>ts;
            is>>ti;
            K=ti;
            break;
        }
        is>>ti;
        number.push_back(ti);
    }
    sort(number.begin(), number.end());
    tri.resize(number.size(),0);
}

void getNum(){
    int he=0;
    for (int i=0; i<number.size(); i++) {
        he+=number[i];
    }
    if(he%K)
        return;
    else{
        tri[0]=1;
        dfs(0,he/K,0,number[0]);
    }
}

int main(){
    string als;
    getline(cin, als);
    funS(als);
    getNum();
    if(result){
        cout<<"True"<<endl;
    }else{
        cout<<"False"<<endl;
    }
}


发表于 2020-05-22 19:24:31 回复(0)
C++ dfs solution
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <string>
using namespace std;

#define is_digit(c)(c >= '0' && c <= '9')

bool kSumdfs(vector<int>& nums, int curr, int target, int k, vector<int>& used)
{
	if (k == 1)
		return true;

	for (int i = 0; i < nums.size(); i++)
	{
		if (nums[i] > curr || used[i] == 1)
			continue;
		else
		{
			used[i] = true;
			if (kSumdfs(nums,
				curr - nums[i] == 0 ? target : curr - nums[i],
				target,
				k - (curr - nums[i] == 0),
				used))
				return true;
			used[i] = false;
		}
	}
	return false;
}

bool kSum(vector<int>& nums, int k)
{
	int sum = 0;
	sort(nums.begin(), nums.end(), greater<int>());
	for (int i = 0; i < nums.size(); i++)
		sum += nums[i];

	if (sum % k != 0) return false;
	vector<int> used(nums.size());
	return kSumdfs(nums, 0, sum / k, k, used);
}

vector<int> preprocess(string s)
{
	vector<int> res;
	int i = 0;
	while (i < s.size())
	{
		if (i == '[' || i == ']')
			continue;
		int digit_start = i;
		int val = 0;
		while (i < s.size() && is_digit(s[i]))
			val = val * 10 + (s[i++] - '0');
		res.push_back(val);
		while (i < s.size() && !is_digit(s[i]))i++;
	}
	return res;
}

int main()
{
	string s;
	char c = 0;
	while (c != '\n')
	{
		cin.get(c);
		s.push_back(c);
	}
		
	vector<int> nums = preprocess(s);
	int k = nums.back();
	nums.pop_back();
	if(kSum(nums, k))
        cout << "True" << endl;
    else
        cout << "False" << endl;
	return 0;
}


编辑于 2020-02-23 13:49:22 回复(0)
import sys
 
 
def find_value(num, value):
    for idx, data in enumerate(num):
        if data<=value:
            num = num[:idx] + num[idx+1:]
            return value-data, num, True
    return value, num, False
 
def check_num(num, k):
    if k==1:
        return True
    num_sum = int(sum(num))
    mean_value = int(num_sum/k)
    if not (mean_value*k % num_sum == 0):
        return False
     
    value = mean_value
    while len(num)>0:
        value, num,rtn = find_value(num, value)
        #rtn, num = sub_list(num, mean_value)
        if not rtn:
            return False
        if value == 0:
            value = mean_value
    return True
 
 
if __name__=="__main__":
    line = sys.stdin.readline().strip()
    num_str, k = line.split(";")
    num = eval(num_str)
    num = [int(data) for data in num]
    k = int(k)
    print(check_num(num, k))


编辑于 2019-09-15 14:26:34 回复(1)
class Solution: def canPartitionKSubsets(self, nums: 'List[int]', k: 'int') -> 'bool': if k == 1: return True sum_num = sum(nums) if sum_num % k != 0: return False avg = sum_num // k
        nums.sort(reverse=True)
        n = len(nums) if n < k :return False visited = set() def dfs(k,tmp_sum,loc): if tmp_sum == avg: # print(visited) return dfs(k-1,0,0) if k == 1: return True for i in range(loc,n): if i not in visited and nums[i] + tmp_sum <= avg:
                    visited.add(i) if dfs(k,tmp_sum+nums[i],i+1): return True visited.remove(i) return False return dfs(k,0,0)
发表于 2019-02-26 10:50:54 回复(0)