zoukankan      html  css  js  c++  java
  • Partition of a set into K subsets with equal sum

    Given an integer array of N elements, the task is to divide this array into K non-empty subsets such that the sum of elements 

    in every subset is same. All elements of this array should be part of exactly one partition. Examples: Input : arr = [2, 1, 4, 5, 6], K = 3 Output : Yes we can divide above array into 3 parts with equal sum as [[2, 4], [1, 5], [6]] Input : arr = [2, 1, 5, 5, 6], K = 3 Output : No It is not possible to divide above array into 3 parts with equal sum

    input check, 正数?  

    In every recursion, we at most try k groups, which means the search tree has k branches at most. And the depth of the search tree is the max number of elements we can put in a group, which is N - k + 1. the time complexity is O(k^(n-k+1)) or O(k^(n-k))

    Assume sum is the sum of nums[] . The dfs process is to find a subset of nums[] which sum equals to sum/k. We use an array visited[]to record which element in nums[] is used. Each time when we get a cur_sum = sum/k, we will start from position 0 in nums[] to look up the elements that are not used yet and find another cur_sum = sum/k.

    An corner case is when sum = 0, my method is to use cur_num to record the number of elements in the current subset. Only if cur_sum = sum/k && cur_num >0, we can start another look up process.

    public boolean canPartitionKSubsets(int[] nums, int k) {
            int sum = 0;
            for(int num:nums)sum += num;
            if(k <= 0 || sum%k != 0)return false;
            int[] visited = new int[nums.length];
            return canPartition(nums, visited, 0, k, 0, 0, sum/k);
        }
        
        public boolean canPartition(int[] nums, int[] visited, int start_index, int k, int cur_sum, int cur_num, int target){
            if(k==1)return true;
            if(cur_sum == target && cur_num>0)return canPartition(nums, visited, 0, k-1, 0, 0, target);
            for(int i = start_index; i<nums.length; i++){
                if(visited[i] == 0){
                    visited[i] = 1;
                    if(canPartition(nums, visited, i+1, k, cur_sum + nums[i], cur_num++, target))return true;
                    visited[i] = 0;
                }
            }
            return false;
        }
    

      

    返回其中一组解:

    public void dfs(List<List<Integer>> ans, List<Integer> list, int[] nums, int k, int[] visited,  int count,int sum,int ave) {
            if (sum == ave && list.size() > 0) {
                ans.add(new ArrayList<>(list));
                if (count == k - 1) {
                    a = true;
                    return;
                }
                dfs(ans, new ArrayList<>(), nums, k, visited, count + 1, 0, ave);
            }
            if (sum > ave) {
                return;
            } else {
                for (int i = 0; i < nums.length; i++) {
                    if (nums[i] + sum > ave || a == true) {
                        return;
                    }
                    if (visited[i] != 1) {
                        sum += nums[i];
                        visited[i] = 1;
                        list.add(nums[i]);
                        dfs(ans, list, nums, k, visited, count, sum, ave);
                        list.remove(list.size() - 1);
                        sum -= nums[i];
                        visited[i] = 0;
                    }
                }
            }
        }
    

      

  • 相关阅读:
    Oracle--pl/sql编程-分支语句(判断、循环)
    axios二次封装及API接口统一管理
    Vuejs之axios获取Http响应头
    对webpack和gulp的理解和区别
    nodejs+redis使用
    Linux安装Nginx、Redis、django
    js 原型里面写方法
    在layui中使用 jquery 触发select 的 change事件无效
    promise看这篇就够了
    vue 封装原型方法 加 promist .then
  • 原文地址:https://www.cnblogs.com/apanda009/p/7940395.html
Copyright © 2011-2022 走看看