首页 > 试题广场 >

划分等和序列

[编程题]划分等和序列
  • 热度指数:728 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个长度为 n 的数组,和一个目标组数 k ,请问能否把这个数组划分成 k 个非空子集,其和都相等。

数据范围: ,数组中的值都满足
示例1

输入

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

输出

true

说明

5|1 4|2 3  
示例2

输入

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

输出

false
public boolean candivide (ArrayList<Integer> nums, int k) {
    int sum = 0;
    for (Integer num : nums) {
        sum += num;
    }
    if (sum % k != 0) {
        return false;
    }
    int target = sum / k;
    int[] dp = new int[target + 1];
    for (Integer num : nums) {
        if (num > target) {
            return false;
        }
        for (int j = target; j >= num; j--) {
            dp[j] = Math.max(dp[j], dp[j - num] + num);
        }
        //我题目理解的有问题,还是案例不够多呀
        //nums = 2,6,3,10,8,4 k = 3时 不能凑出都是11的吧 但是还是返回的true
        if(dp[target] == target){
            return true;
        }
    }
    return false;
}
这样子为什么能过呀,可是nums = 2,6,3,10,8,4 k = 3时 不能凑出都是11的吧 但是还是返回的true
发表于 2022-04-08 15:16:53 回复(1)
# -*- coding: utf-8 -*-

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @param k int整型
# @return bool布尔型
#
class Solution:
    """
    题目:
        https://www.nowcoder.com/practice/89ceab10d36140ce8f0d38c56e417f02?tpId=196&tqId=40516&rp=1&ru=/exam/oj&qru=/exam/oj&sourceUrl=%2Fexam%2Foj%3FjudgeStatus%3D3%26page%3D1%26pageSize%3D50%26search%3D%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196&difficulty=undefined&judgeStatus=3&tags=&title=
    算法:
        1. 边界考虑:
            设nums的长度为n,所有元素和为sum,最大值为maxNum,target = sum / k
            a)如果n < k,无法分割,返回False
            b)如果sum % k != 0,无法分割,返回False
            c) 如果maxNum > target,无法分割,返回False
        2. 回溯函数dfs(k, target)表示当前剩余分割的序列数为k,当前分割区间剩余匹配的目标值为target
            若k == 0,说明分割成功,返回True
            若target == 0,需要分割的区间数-1,继续递归
            枚举当前可选的有效元素,标记为已访问,继续递归;回溯
    复杂度:
        时间复杂度:???
        空间复杂度:O(n)
    """

    def candivide(self, nums, k):
        # write code here
        def dfs(k, remain):
            if k == 0: # 分割序列成功
                return True
            if remain == 0: #
                if dfs(k - 1, target):
                    return True
            for i in range(n):
                if nums[i] > remain&nbs***bsp;visited[i]:  # 当前元素大于剩余匹配值 或者 已被选取
                    continue
                visited[i] = True
                if dfs(k, remain - nums[i]):
                    return True
                visited[i] = False
            return False

        n, Sum = len(nums), sum(nums)
        if n < k&nbs***bsp;Sum % k != 0:
            return False

        nums.sort(reverse=True)
        target = Sum / k
        if nums[0] > target:
            return False

        visited = [False] * n

        return dfs(k, target)


if __name__ == "__main__":
    sol = Solution()

    # nums, k = [5, 1, 3, 2, 4], 3

    nums, k = [5, 1, 4, 2, 3, 2], 3

    res = sol.candivide(nums, k)

    print res

发表于 2022-07-07 21:22:00 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @param k int整型 
     * @return bool布尔型
     */
    #include <vector>
    bool candivide(vector<int>& nums, int k) {
        // write code here    
        int sum=0;
        for(auto& n:nums) sum+=n;
        if(sum%k!=0) return false;
        sort(nums.rbegin(),nums.rend());
        int target=sum/k;
        vector<int> buckets(k,target);
        return dfs(nums,buckets,0);
    }
    
    bool dfs(vector<int>& nums,vector<int>& buckets,int index){
        if(index>=nums.size()) return true;
        for(int i=0;i<buckets.size();i++){
            if(nums[index]>buckets[i]) continue;
            if(i>0&&buckets[i]==buckets[i-1]) continue;
            buckets[i]-=nums[index];
            if(dfs(nums,buckets,index+1)) return true;
            buckets[i]+=nums[index];
        }
        return false;
    }
};

发表于 2022-06-07 11:26:33 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型ArrayList 
     * @param k int整型 
     * @return bool布尔型
     */
    int originTarget = 0;

    public boolean candivide(ArrayList<Integer> nums, int k) {
        // write code here
        int max = 0;
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums.get(i);
            if (nums.get(i) > max) {
                max = nums.get(i);
            }
        }
        if (sum % k != 0) {
            return false;
        }
        // 一个和是多少
        originTarget = sum / k;
        // 最大的大于一个和,肯定不行
        if (max > originTarget) {
            return false;
        }
        // visited数组,标记已访问元素
        boolean[] visited = new boolean[nums.size()];
        return cal(nums, originTarget, visited, k);
    }

    private boolean cal(ArrayList<Integer> nums, int target, boolean[] visited, int k) {
        if (k == 0) {
            return true;
        }
        if (target < 0) {
            return false;
        } else if (target == 0) {
            // 递归k-1,继续访问
            return cal(nums, originTarget, visited, k - 1);
        }
        // target大于0,可以继续回溯
        for (int i = 0; i < nums.size(); i++) {
            if (nums.get(i) > target) {
                continue;
            }
            if (visited[i]) {
                continue;
            }
            visited[i] = true;
            boolean cal = cal(nums, target - nums.get(i), visited, k);
            if (cal) {
                return true;
            }
            visited[i] = false;
        }
        return false;
    }
}

发表于 2022-04-16 14:04:58 回复(0)

问题信息

难度:
4条回答 2556浏览

热门推荐

通过挑战的用户

查看代码