0
点赞
收藏
分享

微信扫一扫

【每日一题见微知著】分割数组的最多方案数

写心之所想 2022-02-26 阅读 27

2025. 分 割 数 组 的 最 多 方 案 数 \textcolor{Red}{2025. 分割数组的最多方案数} 2025.

给你一个下标从 0 开始且长度为 n 的整数数组 nums分割 数组 nums 的方案数定义为符合以下两个条件的 pivot 数目:

  • 1 <= pivot < n
  • nums[0] + nums[1] + ... + nums[pivot - 1] == nums[pivot] + nums[pivot + 1] + ... + nums[n - 1]

同时给你一个整数 k 。你可以将 nums一个 元素变为 k不改变 数组。

请你返回在 至多 改变一个元素的前提下,最多 有多少种方法 分割 nums 使得上述两个条件都满足。

class Solution {
    public int waysToPartition(int[] nums, int k) {
        int n = nums.length;
        int[] preSum = new int[n + 1];
        Map<Integer, Integer> m1 = new HashMap<>();
        Map<Integer, Integer> m2 = new HashMap<>();
        for (int i = 1; i <= n; i++) {
            preSum[i] = nums[i - 1] + preSum[i - 1];
            // 一开始除了最后一个前缀和,其余均在m2中
            if (i != n) m2.put(preSum[i], m2.getOrDefault(preSum[i], 0) + 1);
        }
        int ans = 0;
        if (preSum[n] % 2 == 0) {
            // 若一个元素都不修改
            ans = m2.getOrDefault(preSum[n] / 2, 0);
        }
        for (int i = 0; i < n; i++) {
            // 修改下标为i的元素变成k
            int change = k - nums[i];
            // 所有元素总和的变化量也是change
            int pn = preSum[n] + change;
            if (pn % 2 == 0) {
                // 在m1中我们要找的目标是 target1 = 总和/2 的数量
                int t1 = pn / 2;
                // 在m2中我们要找的目标是 target2 = target1 - change 的数量
                int t2 = t1 - change;
                int found = m1.getOrDefault(t1, 0) + m2.getOrDefault(t2, 0);
                ans = Math.max(ans, found);
            }
            // 不断减少m2中的计数,增加m1对应的计数
            if (i != n - 1) {
                m1.put(preSum[i + 1], m1.getOrDefault(preSum[i + 1], 0) + 1);
                int tmp = m2.get(preSum[i + 1]);
                if (tmp == 1) {
                    m2.remove(preSum[i + 1]);
                } else {
                    m2.put(preSum[i + 1], tmp - 1);
                }
            }
        }
        return ans;
    }

}

//
class Solution {
    public int waysToPartition(int[] nums, int k) {
        int n=nums.length;

        Map<Long,Integer> pre=new HashMap<>();
        Map<Long,Integer> curA=new HashMap<>();

        long[] prefix=new long[n];
        for(int i=0;i<n;i++){
            if(i!=0){
                prefix[i]+=(prefix[i-1]+nums[i]);
            }
            else{
                prefix[i]=nums[i];
            }
        }
        
        int max=0;
        int count0=0;
        
        pre.put((long)(k-nums[0]),0);

        for(int i=1;i<n;i++){
            
            long left=prefix[i-1];
            long right=prefix[n-1]-left;
            
            long c=right-left;
            if(c==0){
                count0++;
                if(count0>max){
                    max=count0;
                }
            }
            
            curA.put(c,curA.getOrDefault(c,0)+1);
            int curMid=curA.getOrDefault((long)(nums[i]-k),0);
            int preMid=pre.getOrDefault(c,-1)+1;
            if(preMid!=0)
                pre.put(c,preMid);

            pre.put((long)(k-nums[i]),Math.max(pre.getOrDefault((long)(k-nums[i]),0),curMid));

            if(max<Math.max(curMid,preMid)){
                max=Math.max(curMid,preMid);
            }
        }
        return max;
    }
}


结尾

举报

相关推荐

0 条评论