返回介绍

solution / 2800-2899 / 2827.Number of Beautiful Integers in the Range / README_EN

发布于 2024-06-17 01:02:59 字数 10760 浏览 0 评论 0 收藏 0

2827. Number of Beautiful Integers in the Range

中文文档

Description

You are given positive integers low, high, and k.

A number is beautiful if it meets both of the following conditions:

  • The count of even digits in the number is equal to the count of odd digits.
  • The number is divisible by k.

Return _the number of beautiful integers in the range_ [low, high].

 

Example 1:

Input: low = 10, high = 20, k = 3
Output: 2
Explanation: There are 2 beautiful integers in the given range: [12,18]. 
- 12 is beautiful because it contains 1 odd digit and 1 even digit, and is divisible by k = 3.
- 18 is beautiful because it contains 1 odd digit and 1 even digit, and is divisible by k = 3.
Additionally we can see that:
- 16 is not beautiful because it is not divisible by k = 3.
- 15 is not beautiful because it does not contain equal counts even and odd digits.
It can be shown that there are only 2 beautiful integers in the given range.

Example 2:

Input: low = 1, high = 10, k = 1
Output: 1
Explanation: There is 1 beautiful integer in the given range: [10].
- 10 is beautiful because it contains 1 odd digit and 1 even digit, and is divisible by k = 1.
It can be shown that there is only 1 beautiful integer in the given range.

Example 3:

Input: low = 5, high = 5, k = 2
Output: 0
Explanation: There are 0 beautiful integers in the given range.
- 5 is not beautiful because it is not divisible by k = 2 and it does not contain equal even and odd digits.

 

Constraints:

  • 0 < low <= high <= 109
  • 0 < k <= 20

Solutions

Solution 1: Digit DP

We notice that the problem is asking for the number of beautiful integers in the interval $[low, high]$. For such an interval $[l,..r]$ problem, we can usually consider transforming it into finding the answers for $[1, r]$ and $[1, l-1]$, and then subtracting the latter from the former. Moreover, the problem only involves the relationship between different digits, not the specific values, so we can consider using Digit DP to solve it.

We design a function $dfs(pos, mod, diff, lead, limit)$, which represents the number of schemes when we are currently processing the $pos$-th digit, the result of the current number modulo $k$ is $mod$, the difference between the odd and even digits of the current number is $diff$, whether the current number has leading zeros is $lead$, and whether the current number has reached the upper limit is $limit$.

The execution logic of the function $dfs(pos, mod, diff, lead, limit)$ is as follows:

If $pos$ exceeds the length of $num$, it means that we have processed all the digits. If $mod=0$ and $diff=0$ at this time, it means that the current number meets the requirements of the problem, so we return $1$, otherwise we return $0$.

Otherwise, we calculate the upper limit $up$ of the current digit, and then enumerate the digit $i$ in the range $[0,..up]$:

  • If $i=0$ and $lead$ is true, it means that the current number only contains leading zeros. We recursively calculate the value of $dfs(pos + 1, mod, diff, 1, limit\ and\ i=up)$ and add it to the answer.
  • Otherwise, we update the value of $diff$ according to the parity of $i$, and then recursively calculate the value of $dfs(pos + 1, (mod \times 10 + i) \bmod k, diff, 0, limit\ and\ i=up)$ and add it to the answer.

Finally, we return the answer.

In the main function, we calculate the answers $a$ and $b$ for $[1, high]$ and $[1, low-1]$ respectively. The final answer is $a-b$.

The time complexity is $O((\log M)^2 \times k \times |\Sigma|)$, and the space complexity is $O((\log M)^2 \times k)$, where $M$ represents the size of the number $high$, and $|\Sigma|$ represents the digit set.

Similar problems:

class Solution:
  def numberOfBeautifulIntegers(self, low: int, high: int, k: int) -> int:
    @cache
    def dfs(pos: int, mod: int, diff: int, lead: int, limit: int) -> int:
      if pos >= len(s):
        return mod == 0 and diff == 10
      up = int(s[pos]) if limit else 9
      ans = 0
      for i in range(up + 1):
        if i == 0 and lead:
          ans += dfs(pos + 1, mod, diff, 1, limit and i == up)
        else:
          nxt = diff + (1 if i % 2 == 1 else -1)
          ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, 0, limit and i == up)
      return ans

    s = str(high)
    a = dfs(0, 0, 10, 1, 1)
    dfs.cache_clear()
    s = str(low - 1)
    b = dfs(0, 0, 10, 1, 1)
    return a - b
class Solution {
  private String s;
  private int k;
  private Integer[][][] f = new Integer[11][21][21];

  public int numberOfBeautifulIntegers(int low, int high, int k) {
    this.k = k;
    s = String.valueOf(high);
    int a = dfs(0, 0, 10, true, true);
    s = String.valueOf(low - 1);
    f = new Integer[11][21][21];
    int b = dfs(0, 0, 10, true, true);
    return a - b;
  }

  private int dfs(int pos, int mod, int diff, boolean lead, boolean limit) {
    if (pos >= s.length()) {
      return mod == 0 && diff == 10 ? 1 : 0;
    }
    if (!lead && !limit && f[pos][mod][diff] != null) {
      return f[pos][mod][diff];
    }
    int ans = 0;
    int up = limit ? s.charAt(pos) - '0' : 9;
    for (int i = 0; i <= up; ++i) {
      if (i == 0 && lead) {
        ans += dfs(pos + 1, mod, diff, true, limit && i == up);
      } else {
        int nxt = diff + (i % 2 == 1 ? 1 : -1);
        ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up);
      }
    }
    if (!lead && !limit) {
      f[pos][mod][diff] = ans;
    }
    return ans;
  }
}
class Solution {
public:
  int numberOfBeautifulIntegers(int low, int high, int k) {
    int f[11][21][21];
    memset(f, -1, sizeof(f));
    string s = to_string(high);

    function<int(int, int, int, bool, bool)> dfs = [&](int pos, int mod, int diff, bool lead, bool limit) {
      if (pos >= s.size()) {
        return mod == 0 && diff == 10 ? 1 : 0;
      }
      if (!lead && !limit && f[pos][mod][diff] != -1) {
        return f[pos][mod][diff];
      }
      int ans = 0;
      int up = limit ? s[pos] - '0' : 9;
      for (int i = 0; i <= up; ++i) {
        if (i == 0 && lead) {
          ans += dfs(pos + 1, mod, diff, true, limit && i == up);
        } else {
          int nxt = diff + (i % 2 == 1 ? 1 : -1);
          ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up);
        }
      }
      if (!lead && !limit) {
        f[pos][mod][diff] = ans;
      }
      return ans;
    };

    int a = dfs(0, 0, 10, true, true);
    memset(f, -1, sizeof(f));
    s = to_string(low - 1);
    int b = dfs(0, 0, 10, true, true);
    return a - b;
  }
};
func numberOfBeautifulIntegers(low int, high int, k int) int {
  s := strconv.Itoa(high)
  f := g(len(s), k, 21)

  var dfs func(pos, mod, diff int, lead, limit bool) int
  dfs = func(pos, mod, diff int, lead, limit bool) int {
    if pos >= len(s) {
      if mod == 0 && diff == 10 {
        return 1
      }
      return 0
    }
    if !lead && !limit && f[pos][mod][diff] != -1 {
      return f[pos][mod][diff]
    }
    up := 9
    if limit {
      up = int(s[pos] - '0')
    }
    ans := 0
    for i := 0; i <= up; i++ {
      if i == 0 && lead {
        ans += dfs(pos+1, mod, diff, true, limit && i == up)
      } else {
        nxt := diff + 1
        if i%2 == 0 {
          nxt -= 2
        }
        ans += dfs(pos+1, (mod*10+i)%k, nxt, false, limit && i == up)
      }
    }
    if !lead && !limit {
      f[pos][mod][diff] = ans
    }
    return ans
  }

  a := dfs(0, 0, 10, true, true)
  s = strconv.Itoa(low - 1)
  f = g(len(s), k, 21)
  b := dfs(0, 0, 10, true, true)
  return a - b
}

func g(m, n, k int) [][][]int {
  f := make([][][]int, m)
  for i := 0; i < m; i++ {
    f[i] = make([][]int, n)
    for j := 0; j < n; j++ {
      f[i][j] = make([]int, k)
      for d := 0; d < k; d++ {
        f[i][j][d] = -1
      }
    }
  }
  return f
}
function numberOfBeautifulIntegers(low: number, high: number, k: number): number {
  let s = String(high);
  let f: number[][][] = Array(11)
    .fill(0)
    .map(() =>
      Array(21)
        .fill(0)
        .map(() => Array(21).fill(-1)),
    );
  const dfs = (pos: number, mod: number, diff: number, lead: boolean, limit: boolean): number => {
    if (pos >= s.length) {
      return mod == 0 && diff == 10 ? 1 : 0;
    }
    if (!lead && !limit && f[pos][mod][diff] != -1) {
      return f[pos][mod][diff];
    }
    let ans = 0;
    const up = limit ? Number(s[pos]) : 9;
    for (let i = 0; i <= up; ++i) {
      if (i === 0 && lead) {
        ans += dfs(pos + 1, mod, diff, true, limit && i === up);
      } else {
        const nxt = diff + (i % 2 ? 1 : -1);
        ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i === up);
      }
    }
    if (!lead && !limit) {
      f[pos][mod][diff] = ans;
    }
    return ans;
  };
  const a = dfs(0, 0, 10, true, true);
  s = String(low - 1);
  f = Array(11)
    .fill(0)
    .map(() =>
      Array(21)
        .fill(0)
        .map(() => Array(21).fill(-1)),
    );
  const b = dfs(0, 0, 10, true, true);
  return a - b;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文