列表

详情


1416. 恢复数组

某个程序本来应该输出一个整数数组。但是这个程序忘记输出空格了以致输出了一个数字字符串,我们所知道的信息只有:数组中所有整数都在 [1, k] 之间,且数组中的数字都没有前导 0 。

给你字符串 s 和整数 k 。可能会有多种不同的数组恢复结果。

按照上述程序,请你返回所有可能输出字符串 s 的数组方案数。

由于数组方案数可能会很大,请你返回它对 10^9 + 7 取余 后的结果。

 

示例 1:

输入:s = "1000", k = 10000
输出:1
解释:唯一一种可能的数组方案是 [1000]

示例 2:

输入:s = "1000", k = 10
输出:0
解释:不存在任何数组方案满足所有整数都 >= 1 且 <= 10 同时输出结果为 s 。

示例 3:

输入:s = "1317", k = 2000
输出:8
解释:可行的数组方案为 [1317],[131,7],[13,17],[1,317],[13,1,7],[1,31,7],[1,3,17],[1,3,1,7]

示例 4:

输入:s = "2020", k = 30
输出:1
解释:唯一可能的数组方案是 [20,20] 。 [2020] 不是可行的数组方案,原因是 2020 > 30 。 [2,020] 也不是可行的数组方案,因为 020 含有前导 0 。

示例 5:

输入:s = "1234567890", k = 90
输出:34

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int numberOfArrays(string s, int k) { } };

golang 解法, 执行用时: 32 ms, 内存消耗: 6.1 MB, 提交时间: 2023-10-26 23:57:04

func numberOfArrays(s string, k int) int {
	mod := int(1e9 + 7)  // 10^9+7 == 1e9+7 不是10e9
	dp := make([]int, len(s)+1)
	dp[0] = 1


	for i := 0; i < len(s); i++ {
		sum := 0
		base := 1
		for j := i; j >= 0&&j>=i-15; j-- { //选定15是因为10^16必定大于k. 这里居然可以省时间
			sum += base * int(s[j]-'0')
			base *= 10
			if sum > k {
				break
			}
			if s[j] != '0' {
				dp[i+1] = (dp[i+1]% mod + dp[j]% mod) % mod
			}
		}
	}
	return dp[len(s)]
}

golang 解法, 执行用时: 28 ms, 内存消耗: 7.1 MB, 提交时间: 2023-10-26 23:56:53

func numberOfArrays(s string, k int) int {
	nums, length := getnumarray(s)
	//var lenofk int = len(string(k))
	var result []int = make([]int, length+1)
	result[0] = 1
	for i := 1; i < length+1; i++ {
		num, base := 0, 1
		j := i - 1
		for ; i-j <= 10 && j >= 0; j-- {
			num += nums[j] * base
			if num > k {
				break
			}
			if nums[j] != 0 {
				result[i] += result[j]
			}
			base = base * 10
		}
		result[i] = nummod(result[i])
	}
	return nummod(result[length])
}

func nummod(result int) int {
	x := float64(result)
	var y float64 = math.Pow10(9) + 7
	return int(math.Mod(x, y))
}

func getnumarray(s string) ([]int, int) {
	bytearray := []byte(s)
	var nums []int = make([]int, len(bytearray))
	for i := 0; i < len(bytearray); i++ {
		nums[i] = int(bytearray[i]) - 48
	}
	return nums, len(bytearray)
}

python3 解法, 执行用时: 1356 ms, 内存消耗: 19.8 MB, 提交时间: 2023-10-26 23:56:18

class Solution:
    def numberOfArrays(self, s: str, k: int) -> int:
        mod = 10**9 + 7
        n = len(s)
        # 递推的边界条件,f[0] = 1
        f = [1] + [0] * n
        for i in range(1, n + 1):
            num, base = 0, 1
            j = i - 1
            # 倒序枚举 j,最多只需要枚举 10 个
            while j >= 0 and i - j <= 10:
                # 在高位添加当前的数字,得到第 j+1 到 i 个数字组成的数
                # 注意 s 的下标是从 0 开始的
                num += (ord(s[j]) - 48) * base
                if num > k:
                    break
                # 判断是否有前导 0
                if s[j] != "0":
                    f[i] += f[j]
                base *= 10
                j -= 1
            f[i] %= mod
        return f[n]

java 解法, 执行用时: 38 ms, 内存消耗: 43.1 MB, 提交时间: 2023-10-26 23:56:03

class Solution {
    public int numberOfArrays(String s, int k) {
        final int MOD = 1000000007;
        int n = s.length();
        // 为了便于代码编写,我们使用 64 位整数类型
        long kLong = k;
        int[] f = new int[n + 1];
        // 递推的边界条件
        f[0] = 1;
        for (int i = 1; i <= n; ++i) {
            long num = 0, base = 1;
            // 倒序枚举 j,最多只需要枚举 10 个
            for (int j = i - 1; j >= 0 && i - j <= 10; --j) {
                // 在高位添加当前的数字,得到第 j+1 到 i 个数字组成的数
                // 注意 s 的下标是从 0 开始的
                num += (s.charAt(j) - '0') * base;
                if (num > kLong) {
                    break;
                }
                // 判断是否有前导 0
                if (s.charAt(j) != '0') {
                    f[i] += f[j];
                    f[i] %= MOD;
                }
                base *= 10;
            }
        }
        return f[n];
    }
}

cpp 解法, 执行用时: 52 ms, 内存消耗: 12.1 MB, 提交时间: 2023-10-26 23:55:49

using LL = long long;

class Solution {
private:
    static constexpr int mod = 1000000007;

public:
    int numberOfArrays(string s, int k) {
        int n = s.size();
        // 为了便于代码编写,我们使用 64 位整数类型
        LL kll = k;
        vector<int> f(n + 1, 0);
        // 递推的边界条件
        f[0] = 1;
        for (int i = 1; i <= n; ++i) {
            LL num = 0, base = 1;
            // 倒序枚举 j,最多只需要枚举 10 个
            for (int j = i - 1; j >= 0 && i - j <= 10; --j) {
                // 在高位添加当前的数字,得到第 j+1 到 i 个数字组成的数
                // 注意 s 的下标是从 0 开始的
                num += (s[j] - '0') * base;
                if (num > kll) {
                    break;
                }
                // 判断是否有前导 0
                if (s[j] != '0') {
                    f[i] += f[j];
                    f[i] %= mod;
                }
                base *= 10;
            }
        }
        return f[n];
    }
};

java 解法, 执行用时: 226 ms, 内存消耗: 44.9 MB, 提交时间: 2023-10-26 23:55:35

class Solution {
    public int numberOfArrays(String s, int k) {
        int n = s.length();
        int[] dp = new int[n+1];
        for (int i = 0; i<n; i++) dp[i] = 0;
        dp[0] = 1;
        int m = 1000000007;
        for (int i = 1; i<=n; i++){
            for (int j = i-1; j>=0; j--){
                if (s.charAt(j) == '0') continue;
                //i比对应的元素下标要大1,即i=1时对应s[0]
                if (Long.valueOf(s.substring(j,i)) <=k){
                    dp[i] = (dp[i]+ dp[j]) % m;
                } else {
                    if (s.charAt(i-1) == '0' && dp[i] == 0)return 0;
                    break;
                }
            }
            dp[i] %= m;
        }
        return dp[n]%m;
    }
}

python3 解法, 执行用时: 1052 ms, 内存消耗: 20.1 MB, 提交时间: 2023-10-26 23:55:14

class Solution:
    def numberOfArrays(self, s: str, k: int) -> int:
        n = len(s)
        dp = [0] * (n + 1)
        dp[0] = 1
        mod = 10 ** 9 + 7
        
        for i in range(1, n + 1):
            for j in range(i - 1, -1, -1):
                if s[j] == "0": continue
                if int(s[j:i]) <= k:
                    dp[i] += dp[j]
                else:
                    if s[i - 1] == "0" and dp[i] == 0: return 0
                    break

            dp[i] %= mod
                
        #print(dp)
        return dp[-1] % mod

上一题