首页 > 试题广场 >

填充数组

[编程题]填充数组
  • 热度指数:4415 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

牛妹给了牛牛一个长度为 的下标从开始的正整型数组 ,粗心的牛牛不小心把其中的一些数字删除了。

假如被删除了,则。对于所有被删除的数字,牛牛必须选择一个正整数填充上。现在牛牛想知道有多少种填充方案使得:

  • 且对于所有的满足

函数传入一个下标从开始的数组 和一个正整数 ,请返回合法的填充方案数对 取模的值,保证不存在方案数为0的数据。

示例1

输入

[0,4,5],6

输出

4

说明

所有的合法填充方案是:[1,4,5],[2,4,5],[3,4,5],[4,4,5],共4种。   
示例2

输入

[1,0,0],3

输出

6

说明

所有的合法填充方案是:[1,1,1],[1,1,2],[1,2,2],[1,2,3],[1,3,3],[1,1,3]共6种   
示例3

输入

[0,0,0,0,0,67,0,0],100

输出

746845806

备注:

数组满足

import java.util.*;
import java.math.BigInteger;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param a int整型一维数组 
     * @param k int整型 
     * @return int整型
     */
    public int FillArray (int[] a, int k) {
        long answer = 1;
         
        int index = 0;
        while(index < a.length) {
            int zero_num = 0;
            int min = 1;
            int max = k;
            if(index-1>=0)
                min = a[index-1];
            if(a[index] == 0) {
                while(a[index] == 0) {
                    zero_num++;
                    index++;
                    if(index >= a.length)
                        break;
                }
                if(index < a.length)
                    max = a[index];
                int[] list = new int[max-min+1];
                for (int i = 0; i < list.length; i++) {
                    list[i] = 1;
                }
                for (int i = 1; i < zero_num; i++) {
                    for (int j = 0; j < list.length; j++) {
                        for (int j2 = j+1; j2 < list.length; j2++) {
                            list[j] = (list[j]+list[j2]) % (int)(Math.pow(10, 9)+7);
                        }
                    }
                }
                int sum = 0;
                for (int i = 0; i < list.length; i++) {
                    sum = (sum+list[i]) % (int)(Math.pow(10, 9)+7);
                }
                answer = (answer*sum) % (int)(Math.pow(10, 9)+7);
            }else {
                index++;
            }
        }
        return (int)answer;
    }
}
发表于 2022-03-07 18:11:05 回复(0)
运行时间70ms
占用内存14716KB
   1.必须要使用BigInteger,不然会溢出;
    2.方案数拆开来其实是个简单的数列自增问题
    3.fillZero方法是关键(不要递归,递归效率会崩)因为太久不做数学题导致敏感性下降,结果很简单的问题本来看懂了规律却没想出来公式,只能套递归,崩了,参考了评论里的第一条才想明白公式原来这么简单,看来人已经废了...

    public int FillArray (int[] a, int k) {
        // write code here
        return findSolution(a,k).mod(BigInteger.valueOf(1000000007)).intValue();
    }
    private BigInteger findSolution (int[] a, int k) {
        int[] b = new int[a.length+2];
        b[0] = 1;
        b[b.length-1] = k;
        System.arraycopy(a,0,b,1,a.length);

        BigInteger res = BigInteger.ONE;
        int begin=1;
        int lastIndex = b.length-1;

        while(begin<lastIndex){
            while(0!=b[begin]){
                if (lastIndex == begin) return res;
                begin++;
            }
            int min= b[begin-1];
            int zero=0;
            while(0==b[begin]){
                zero++;
                begin++;
            }
            int max= b[begin];
            int sols= max-min+1;
            res = res.multiply(fillZero(sols,zero));
        }
        return res;
    }

   private BigInteger fillZero (int sols, int zero) {
        if (zero > 1) {
            BigInteger[] prob = new BigInteger[sols];
            for (int i=0;i<sols;i++){
                prob[i]= BigInteger.valueOf(i+1);
            }
            while (zero-->1){
                BigInteger[] temp = new BigInteger[sols];
                for (int j=1;j<sols;j++){
                    prob[j]=prob[j-1].add(prob[j]);
                }
            }
            return prob[sols-1];
        } else {
            return BigInteger.valueOf(sols);
        }
    }
编辑于 2021-12-13 23:58:52 回复(0)