Daily LC:数组均分

描述:一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
case:比如{3,2,4,3,6} 可以分成
    {3,2,4,3,6} m=1;
    {3,6}{2,4,3} m=2     {3,3}{2,4}{6} m=3 所以m的最大值为3

思路分析:
隐性要求:total%m==0,且m的取值范围为1<m<=n;
求m的最大值,则让m从n开始递减,找到第一个符合条件的m返回即可,如果没有则返回1。
设数组为nums,数组的和为sum,设一临时数组store来存储分组情况,groupId表示分组编号store[i]=1,则说明a[i]分在第一组。
  当sum%m!=0时,表示无法均分,直接跳过;
  当sum%m==0时,遍历数组中每个元素,若当前元素状态为未分配,即store[i]=0,将其分配到相应组中,并基于分配状态进行结果判断:
      a.若组内元素和>sum/m,则说明当前元素无法加入,令store[i]=0;
      b.若组内元素和=sum/m,则令groupId++,继续遍历,判断下一组;
      c.若组内元素和<sum/m,则将当前元素加入该组,状态改为已选,store[i]=组号,继续进行下一个元素的判断;

代码:

public class Main {
    public static void main(String[] args) {
        int[] nums=new int[]{3,2,4,3,6};
        System.out.println(maxPartition(nums));
    }
    static int maxPartition(int[] nums){
        int n=nums.length;
        if(n<=1){
            return n;
        }
        int sum=0;
        for(int num:nums){
            sum+=num;
        }
        int[] store=new int[n];
        for(int m=n;m>=2;m--){
            if(sum%m!=0){
                continue;
            }
           for(int i=0;i<n;i++){
               store[i]=0;
           }
            if(tryPartition(nums,n,m,sum,sum/m,store,sum/m,1)){
                return m;
            }
        }
        return 1;
    }
    
    static boolean tryPartition(int[] nums,int n,int m,int sum,int groupSum,int[]store,int goal,int groupId){
        if(goal<0){
            return false;
        }
        if(goal==0){
            groupId++;
            goal=groupSum;
            if(groupId==m+1){
                return true;
            }
        }
        for(int i=0;i<n;i++){
            if(store[i]!=0){
                continue;
            }
            store[i]=groupId;
            if(tryPartition(nums,n,m,sum,groupSum,store,goal-nums[i],groupId)){
                return true;
            }else{
                 store[i]=0;
            }
        }
        return false;
    }
}

 



posted @ 2024-06-26 21:28  csbdong  阅读(105)  评论(0编辑  收藏  举报