Skip to content

Commit f7a94a5

Browse files
committed
leetcode
1 parent 727c2f2 commit f7a94a5

File tree

4 files changed

+288
-0
lines changed

4 files changed

+288
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
3+
4+
-* Number of Dice Rolls With Target Sum *-
5+
6+
You have n dice and each die has k faces numbered from 1 to k.
7+
8+
Given three integers n, k, and target, return the number of possible ways (out of the kn total ways) to roll the dice so the sum of the face-up numbers equals target. Since the answer may be too large, return it modulo 109 + 7.
9+
10+
11+
12+
Example 1:
13+
14+
Input: n = 1, k = 6, target = 3
15+
Output: 1
16+
Explanation: You throw one die with 6 faces.
17+
There is only one way to get a sum of 3.
18+
Example 2:
19+
20+
Input: n = 2, k = 6, target = 7
21+
Output: 6
22+
Explanation: You throw two dice, each with 6 faces.
23+
There are 6 ways to get a sum of 7: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1.
24+
Example 3:
25+
26+
Input: n = 30, k = 30, target = 500
27+
Output: 222616187
28+
Explanation: The answer must be returned modulo 109 + 7.
29+
30+
31+
Constraints:
32+
33+
1 <= n, k <= 30
34+
1 <= target <= 1000
35+
36+
37+
*/
38+
39+
// DP Approach- Tabulation
40+
import 'dart:collection';
41+
42+
class A {
43+
// Runtime: 529 ms, faster than 100.00% of Dart online submissions for Number of Dice Rolls With Target Sum.
44+
// Memory Usage: 143.7 MB, less than 100.00% of Dart online submissions for Number of Dice Rolls With Target Sum.
45+
46+
int numRollsToTarget(int n, int k, int target) {
47+
//int mod = (1e9 + 7).floor();
48+
int m = 1000000007;
49+
List<List<int>> dp =
50+
List.filled(n + 1, 0).map((e) => List.filled(target + 1, 0)).toList();
51+
dp[0][0] = 1;
52+
for (int i = 1; i <= n; i++) {
53+
for (int j = 1; j <= target; j++) {
54+
for (int r = 1; r <= k; r++) {
55+
if (r <= j) dp[i][j] = ((dp[i][j] % m) + (dp[i - 1][j - r] % m)) % m;
56+
}
57+
}
58+
}
59+
return dp[n][target];
60+
}
61+
}
62+
63+
class B {
64+
// Memoization but TLC
65+
int numRollsToTarget(int n, int k, int target) {
66+
//int mod = (1e9 + 7).floor();
67+
int MOD = 1000000007;
68+
// HashMap to unique elements because we don't wanna repeat
69+
HashMap<int, int> mem = HashMap();
70+
// if our target and side is end up 0 than we will return 1
71+
if (n == 0 && target == 0) return 1;
72+
// if the face is OR the target is less or equal to zero return zeo
73+
if (n <= 0 || target <= 0) return 0;
74+
// our key in the HAsh map to hold the value
75+
int key = n + "_".codeUnitAt(0) + target;
76+
// if we find the we will simply return the key based on the index we have found
77+
if (mem.containsKey(key)) return mem.keys.elementAt(key);
78+
// holding our value
79+
int ans = 0;
80+
// loop to iterate through the target value and face value of the dice
81+
for (int i = 1; i <= k && i <= target; i++) {
82+
// getting the MOD recursively
83+
ans = (ans + numRollsToTarget(n - 1, k, target - i)) % MOD;
84+
}
85+
// putting the value inside our hashMap
86+
mem.forEach((key, value) {
87+
key = key;
88+
value = ans;
89+
});
90+
// return the value
91+
return ans;
92+
}
93+
}
94+
95+
class C {
96+
// Recursive
97+
// Correct but TLC
98+
/// > The number of ways to get to `target` using `n` dice with `k` sides is the sum of the number of
99+
/// ways to get to `target - 1` through `target - k` using `n - 1` dice with `k` sides
100+
///
101+
/// Args:
102+
/// n (int): number of dice
103+
/// k (int): the maximum number that can be used in the sum
104+
/// target (int): the sum of the numbers
105+
///
106+
/// Returns:
107+
/// The number of ways to sum to target using n numbers from 1 to k.
108+
int solve(int n, int k, int target) {
109+
if (n == 0 && target == 0) return 1;
110+
111+
if (n <= 0 || target <= 0) return 0;
112+
113+
int ans = 0;
114+
for (int i = 1; i <= k; i++) ans += solve(n - 1, k, target - i);
115+
116+
return ans;
117+
}
118+
119+
int numRollsToTarget(int n, int k, int target) {
120+
return solve(n, k, target);
121+
}
122+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
// func solve(n int, k int, target int) int {
4+
// if n == 0 && target == 0 {
5+
// return 1
6+
// }
7+
8+
// if n <= 0 || target <= 0 {
9+
// return 0
10+
// }
11+
12+
// ans := 0
13+
// for i := 1; i <= k; i++ {
14+
// ans += solve(n-1, k, target-i)
15+
// }
16+
17+
// return ans
18+
// }
19+
20+
// func numRollsToTarget(n int, k int, target int) int {
21+
// return solve(n, k, target)
22+
// }
23+
24+
func numRollsToTarget(n int, k int, target int) int {
25+
const mod int = 1e9 + 7
26+
var ans [1001]int
27+
for i := 1; i <= k; i++ {
28+
ans[i] = 1
29+
}
30+
for n--; n > 0; n-- {
31+
var last, sum = ans, 0
32+
for i := 1; i <= target; i++ {
33+
sum += last[i-1]
34+
if i-k-1 > 0 {
35+
sum -= last[i-k-1]
36+
}
37+
ans[i] = sum % mod
38+
}
39+
}
40+
return ans[target]
41+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# 🔥 Number of Dice Rolls With Target Sum 🔥 || 3 Solutions || Simple Fast and Easy || with Explanation
2+
3+
## Solution - 1 DP Tabulation Bottom Up
4+
5+
### Explanation
6+
7+
As an initial example, pretend we have 5 dice with 6 faces each and we want to determine how many ways to make 18.
8+
9+
In other words, what is dp(5, 6, 18)?
10+
11+
At first glance, this seems difficult and overwhelming. But if we make one simple observation, we can reduce this big problem into several smaller sub-problems. We have 5 dice, but let’s first just look at ONE of these dice (say the last one). This die can take on f=6 different values (1 to 6), so we consider what happens when we fix its value to each possibility (6 cases):
12+
13+
- Case 1: The last die is a 1. The remaining 4 dice must sum to 18-1=17. This can happen dp(4, 6, 17) ways.
14+
- Case 2: The last die is a 2. The remaining 4 dice must sum to 18-2=16. This can happen dp(4, 6, 16) ways.
15+
- Case 3: The last die is a 3. The remaining 4 dice must sum to 18-3=15. This can happen dp(4, 6, 15) ways.
16+
- Case 4: The last die is a 4. The remaining 4 dice must sum to 18-4=14. This can happen dp(4, 6, 14) ways.
17+
- Case 5: The last die is a 5. The remaining 4 dice must sum to 18-5=13. This can happen dp(4, 6, 13) ways.
18+
- Case 6: The last die is a 6. The remaining 4 dice must sum to 18-6=12. This can happen dp(4, 6, 12) ways.
19+
20+
dp(5, 6, 18) = dp(4, 6, 17) + dp(4, 6, 16) + dp(4, 6, 15) + dp(4, 6, 14) + dp(4, 6, 13) + dp(4, 6, 12)
21+
22+
We sum up the solutions in these 6 cases to arrive at our result. Of course, each of these cases branches off into 6 cases of its own, and the recursion only resolves when d=0. The handling of this base case is explained below.
23+
The general relation is:
24+
25+
dp(d, f, target) = dp(d-1, f, target-1) + dp(d-1, f, target-2) + … + dp(d-1, f, target-f)
26+
27+
The base case occurs when d = 0. We can make target=0 with 0 dice, but nothing else.
28+
So dp(0, f, t) = 0 iff t != 0, and dp(0, f, 0) = 1.
29+
30+
Time Complexity
31+
O(d *target* faces)
32+
33+
Space Complexity
34+
O(d * target)
35+
36+
```dart
37+
class Solution {
38+
// Runtime: 529 ms, faster than 100.00% of Dart online submissions for Number of Dice Rolls With Target Sum.
39+
// Memory Usage: 143.7 MB, less than 100.00% of Dart online submissions for Number of Dice Rolls With Target Sum.
40+
41+
int numRollsToTarget(int n, int k, int target) {
42+
// int mod = (1e9 + 7).floor();
43+
int m = 1000000007;
44+
List<List<int>> dp =
45+
List.filled(n + 1, 0).map((e) => List.filled(target + 1, 0)).toList();
46+
dp[0][0] = 1;
47+
for (int i = 1; i <= n; i++) {
48+
for (int j = 1; j <= target; j++) {
49+
for (int r = 1; r <= k; r++) {
50+
if (r <= j) dp[i][j] = ((dp[i][j] % m) + (dp[i - 1][j - r] % m)) % m;
51+
}
52+
}
53+
}
54+
return dp[n][target];
55+
}
56+
}
57+
```
58+
59+
## Solution - 2 Memoization HashMap - TLC
60+
61+
```dart
62+
class Solution {
63+
int numRollsToTarget(int n, int k, int target) {
64+
// mod value
65+
// int mod = (1e9 + 7).floor();
66+
int MOD = 1000000007;
67+
// HashMap to unique elements because we don't wanna repeat
68+
HashMap<int, int> mem = HashMap();
69+
// if our target and side is end up 0 than we will return 1
70+
if (n == 0 && target == 0) return 1;
71+
// if the face is OR the target is less or equal to zero return zeo
72+
if (n <= 0 || target <= 0) return 0;
73+
// our key in the HAsh map to hold the value
74+
int key = n + "_".codeUnitAt(0) + target;
75+
// if we find the we will simply return the key based on the index we have found
76+
if (mem.containsKey(key)) return mem.keys.elementAt(key);
77+
// holding our value
78+
int ans = 0;
79+
// loop to iterate through the target value and face value of the dice
80+
for (int i = 1; i <= k && i <= target; i++) {
81+
// getting the MOD recursively
82+
ans = (ans + numRollsToTarget(n - 1, k, target - i)) % MOD;
83+
}
84+
// putting the value inside our hashMap
85+
mem.forEach((key, value) {
86+
key = key;
87+
value = ans;
88+
});
89+
// return the value
90+
return ans;
91+
}
92+
}
93+
```
94+
95+
## Solution - 3 Recursive Brute Force - TLC
96+
97+
```dart
98+
class Solution {
99+
/// > The number of ways to get to `target` using `n` dice with `k` sides is the sum of the number of
100+
/// ways to get to `target - 1` through `target - k` using `n - 1` dice with `k` sides
101+
///
102+
/// Args:
103+
/// n (int): number of dice
104+
/// k (int): the maximum number that can be used in the sum
105+
/// target (int): the sum of the numbers
106+
///
107+
/// Returns:
108+
/// The number of ways to sum to target using n numbers from 1 to k.
109+
int solve(int n, int k, int target) {
110+
if (n == 0 && target == 0) return 1;
111+
112+
if (n <= 0 || target <= 0) return 0;
113+
114+
int ans = 0;
115+
for (int i = 1; i <= k; i++) ans += solve(n - 1, k, target - i);
116+
117+
return ans;
118+
}
119+
120+
int numRollsToTarget(int n, int k, int target) {
121+
return solve(n, k, target);
122+
}
123+
}
124+
```

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
6868
- [Number of 1 Bits](NumberOf-1-Bits/number_of_1_bits.dart)
6969
- [Reverse Bits](ReverseBits/reverse_bits.dart)
7070
- [Happy Number](HappyNumber/happy_number.dart)
71+
- [Number of Dice Rolls With Target Sum](NumberOfDiceRollsWithTargetSum/number_of_dice_rolls_with_target_sum.dart)
7172

7273
## Reach me via
7374

0 commit comments

Comments
 (0)