Dotā virknē, kas sastāv no cipariem 0-9, saskaitiet tajā esošo apakšsecību skaitu, kas dalās ar m.
Piemēri:
Input : str = '1234' n = 4
Output : 4
The subsequences 4 12 24 and 124 are
divisible by 4.
Input : str = '330' n = 6
Output : 4
The subsequences 30 30 330 and 0 are
divisible by n.
Input : str = '676' n = 6
Output : 3
The subsequences 6 6 and 66
Šo problēmu var definēt rekursīvi. Ļaujiet virknes ar vērtību x atlikušajai daļai būt “r”, dalītu ar n. Pievienojot šai virknei vēl vienu rakstzīmi, tās atlikums tiek mainīts uz (r*10 + jauns cipars) % n. Katrai jaunai rakstzīmei mums ir divas izvēles iespējas vai nu pievienot to visām pašreizējām apakšsecībām, vai arī ignorēt. Tādējādi mums ir optimāla apakšstruktūra. Tālāk ir parādīta šī brutālā spēka versija:
string str = '330';
int n = 6
// idx is value of current index in str
// rem is current remainder
int count(int idx int rem)
{
// If last character reached
if (idx == n)
return (rem == 0)? 1 : 0;
int ans = 0;
// we exclude it thus remainder
// remains the same
ans += count(idx+1 rem);
// we include it and thus new remainder
ans += count(idx+1 (rem*10 + str[idx]-'0')%n);
return ans;
}
Iepriekš minētajam rekursīvajam risinājumam ir apakšproblēmas, kas pārklājas, kā parādīts zemāk esošajā rekursijas kokā.
input string = '330'
(00) ===> at 0th index with 0 remainder
(exclude 0th / (include 0th character)
character) /
(10) (13) ======> at index 1 with 3 as
(E)/ (I) /(E) the current remainder
(20) (23) (23)
|-------|
These two subproblems overlap
Tādējādi mēs varam izmantot dinamisko programmēšanu. Zemāk ir tā ieviešana.
// C++ program to count subsequences of a // string divisible by n. #include using namespace std; // Returns count of subsequences of str // divisible by n. int countDivisibleSubseq(string str int n) { int len = str.length(); // division by n can leave only n remainder // [0..n-1]. dp[i][j] indicates number of // subsequences in string [0..i] which leaves // remainder j after division by n. int dp[len][n]; memset(dp 0 sizeof(dp)); // Filling value for first digit in str dp[0][(str[0]-'0')%n]++; for (int i=1; i<len; i++) { // start a new subsequence with index i dp[i][(str[i]-'0')%n]++; for (int j=0; j<n; j++) { // exclude i'th character from all the // current subsequences of string [0...i-1] dp[i][j] += dp[i-1][j]; // include i'th character in all the current // subsequences of string [0...i-1] dp[i][(j*10 + (str[i]-'0'))%n] += dp[i-1][j]; } } return dp[len-1][0]; } // Driver code int main() { string str = '1234'; int n = 4; cout << countDivisibleSubseq(str n); return 0; }
Java //Java program to count subsequences of a // string divisible by n class GFG { // Returns count of subsequences of str // divisible by n. static int countDivisibleSubseq(String str int n) { int len = str.length(); // division by n can leave only n remainder // [0..n-1]. dp[i][j] indicates number of // subsequences in string [0..i] which leaves // remainder j after division by n. int dp[][] = new int[len][n]; // Filling value for first digit in str dp[0][(str.charAt(0) - '0') % n]++; for (int i = 1; i < len; i++) { // start a new subsequence with index i dp[i][(str.charAt(i) - '0') % n]++; for (int j = 0; j < n; j++) { // exclude i'th character from all the // current subsequences of string [0...i-1] dp[i][j] += dp[i - 1][j]; // include i'th character in all the current // subsequences of string [0...i-1] dp[i][(j * 10 + (str.charAt(i) - '0')) % n] += dp[i - 1][j]; } } return dp[len - 1][0]; } // Driver code public static void main(String[] args) { String str = '1234'; int n = 4; System.out.print(countDivisibleSubseq(str n)); } } // This code is contributed by 29AjayKumar
Python 3 # Python 3 program to count subsequences # of a string divisible by n. # Returns count of subsequences of # str divisible by n. def countDivisibleSubseq(str n): l = len(str) # division by n can leave only n remainder # [0..n-1]. dp[i][j] indicates number of # subsequences in string [0..i] which leaves # remainder j after division by n. dp = [[0 for x in range(l)] for y in range(n)] # Filling value for first digit in str dp[int(str[0]) % n][0] += 1 for i in range(1 l): # start a new subsequence with index i dp[int(str[i]) % n][i] += 1 for j in range(n): # exclude i'th character from all the # current subsequences of string [0...i-1] dp[j][i] += dp[j][i-1] # include i'th character in all the current # subsequences of string [0...i-1] dp[(j * 10 + int(str[i])) % n][i] += dp[j][i-1] return dp[0][l-1] # Driver code if __name__ == '__main__': str = '1234' n = 4 print(countDivisibleSubseq(str n)) # This code is contributed by ita_c
C# //C# program to count subsequences of a // string divisible by n using System; class GFG { // Returns count of subsequences of str // divisible by n. static int countDivisibleSubseq(string str int n) { int len = str.Length; // division by n can leave only n remainder // [0..n-1]. dp[i][j] indicates number of // subsequences in string [0..i] which leaves // remainder j after division by n. int[] dp = new int[lenn]; // Filling value for first digit in str dp[0(str[0] - '0') % n]++; for (int i = 1; i < len; i++) { // start a new subsequence with index i dp[i(str[i] - '0') % n]++; for (int j = 0; j < n; j++) { // exclude i'th character from all the // current subsequences of string [0...i-1] dp[ij] += dp[i - 1j]; // include i'th character in all the current // subsequences of string [0...i-1] dp[i(j * 10 + (str[i] - '0')) % n] += dp[i - 1j]; } } return dp[len - 10]; } // Driver code public static void Main() { String str = '1234'; int n = 4; Console.Write(countDivisibleSubseq(str n)); } }
JavaScript <script> //Javascript program to count subsequences of a // string divisible by n // Returns count of subsequences of str // divisible by n. function countDivisibleSubseq(strn) { let len = str.length; // division by n can leave only n remainder // [0..n-1]. dp[i][j] indicates number of // subsequences in string [0..i] which leaves // remainder j after division by n. let dp = new Array(len); for(let i = 0; i < len; i++) { dp[i] = new Array(n); for(let j = 0; j < n; j++) { dp[i][j] = 0; } } // Filling value for first digit in str dp[0][(str[0] - '0') % n]++; for (let i = 1; i < len; i++) { // start a new subsequence with index i dp[i][(str[i] - '0') % n]++; for (let j = 0; j < n; j++) { // exclude i'th character from all the // current subsequences of string [0...i-1] dp[i][j] += dp[i - 1][j]; // include i'th character in all the current // subsequences of string [0...i-1] dp[i][(j * 10 + (str[i] - '0')) % n] += dp[i - 1][j]; } } return dp[len - 1][0]; } // Driver code let str = '1234'; let n = 4; document.write(countDivisibleSubseq(str n)); // This code is contributed by avanitrachhadiya2155 </script>
Izvade
4
Laika sarežģītība: O (len * n)
Palīgtelpa: O (len * n)
Efektīva pieeja: telpas optimizācija
Iepriekšējā pieejā dp[i][j] ir atkarīga no pašreizējās un iepriekšējās 2D matricas rindas. Tātad, lai optimizētu telpu, mēs izmantojam divus vektorus temp un dp kas seko pašreizējai un iepriekšējai rindai DP .
Ieviešanas soļi:
- The countDivisibleSubseq funkcija saskaita apakšsecību skaitu dotajā virknē str, kas dalās ar noteiktu skaitli n.
- Tas inicializē masīvu dp izmēra n lai saglabātu skaitu.
- Tas atkārto katru virknes ciparu un atjaunina skaitu dp pamatojoties uz atlikumiem.
- Katrā iterācijā tas ņem vērā pašreizējo ciparu un iepriekšējos skaitļus, lai aprēķinātu atjaunināto skaitu.
- Visbeidzot tas atgriež ar n dalīto apakšsekvenču skaitu, kas saglabātas dp[0] .
Īstenošana:
C++#include using namespace std; int countDivisibleSubseq(string str int n) { int len = str.length(); int dp[n]; memset(dp 0 sizeof(dp)); dp[(str[0]-'0')%n]++; // Increment the count of remainder of first digit by n for (int i=1; i<len; i++) { int temp[n]; memset(temp 0 sizeof(temp)); temp[(str[i]-'0')%n]++; // Increment the count of remainder of current digit by n for (int j=0; j<n; j++) { temp[j] += dp[j]; // Carry over the counts from previous digit temp[(j*10 + (str[i]-'0'))%n] += dp[j]; // Update the count with the new remainder formed by appending the current digit } for (int j=0; j<n; j++) { dp[j] = temp[j]; // Copy the updated counts from temp back to dp for the next iteration } } return dp[0]; // Return the count of subsequences divisible by n } int main() { string str = '1234'; int n = 4; cout << countDivisibleSubseq(str n); return 0; }
Java // Java program to count subsequences // of a string divisible by n. public class GFG { public static int countDivisibleSubseq(String str int n) { int length = str.length(); int[] dp = new int[n]; // Create an array of size n to store counts // Increment the count of remainder of first digit by n dp[Integer.parseInt(String.valueOf(str.charAt(0))) % n] += 1; for (int i = 1; i < length; i++) { int[] temp = new int[n]; // Create a temporary array of size n // Increment the count of remainder of current digit by n temp[Integer.parseInt(String.valueOf(str.charAt(i))) % n] += 1; for (int j = 0; j < n; j++) { temp[j] += dp[j]; // Carry over the counts from the previous digit // Calculate the new remainder int newRemainder = (j * 10 + Integer.parseInt(String.valueOf(str.charAt(i)))) % n; // Update the count with the new remainder temp[newRemainder] += dp[j]; } dp = temp; } return dp[0]; } //Driver code public static void main(String[] args) { String str = '1234'; int n = 4; System.out.println(countDivisibleSubseq(str n)); } }
Python3 # Python 3 program to count subsequences # of a string divisible by n. def countDivisibleSubseq(str n): length = len(str) dp = [0] * n # Create an array of size n # Increment the count of remainder of first digit by n dp[int(str[0]) % n] += 1 for i in range(1 length): temp = [0] * n # Create a temporary array of size n # Increment the count of remainder of current digit by n temp[int(str[i]) % n] += 1 for j in range(n): temp[j] += dp[j] # Carry over the counts from the previous digit # Calculate the new remainder new_remainder = (j * 10 + int(str[i])) % n # Update the count with the new remainder temp[new_remainder] += dp[j] dp = temp return dp[0] # Driver code str = '1234' n = 4 print(countDivisibleSubseq(str n))
C# using System; class GFG { static int CountDivisibleSubseq(string str int n) { int len = str.Length; int[] dp = new int[n]; Array.Fill(dp 0); dp[(str[0] - '0') % n]++; // Increment the count of remainder of // first digit by n for (int i = 1; i < len; i++) { int[] temp = new int[n]; Array.Fill(temp 0); temp[(str[i] - '0') % n]++; // Increment the count of remainder // of current digit by n for (int j = 0; j < n; j++) { temp[j] += dp[j]; // Carry over the counts // from previous digit temp[(j * 10 + (str[i] - '0')) % n] += dp[j]; // Update the count with the // new remainder formed by // appending the current digit } for (int j = 0; j < n; j++) { dp[j] = temp[j]; // Copy the updated counts // from temp back to dp for // the next iteration } } return dp[0]; // Return the count of subsequences // divisible by n } static void Main() { string str = '1234'; int n = 4; Console.WriteLine(CountDivisibleSubseq(str n)); } }
JavaScript function countDivisibleSubseq(str n) { const len = str.length; const dp = new Array(n).fill(0); // Increment the count of remainder of first digit by n dp[Number(str[0]) % n]++; for (let i = 1; i < len; i++) { const temp = new Array(n).fill(0); // Increment the count of remainder of current digit by n temp[Number(str[i]) % n]++; for (let j = 0; j < n; j++) { temp[j] += dp[j]; // Carry over the counts from previous digit // Update the count with the new remainder // formed by appending the current digit temp[(j * 10 + Number(str[i])) % n] += dp[j]; } for (let j = 0; j < n; j++) { // Copy the updated counts from // temp back to dp for the next iteration dp[j] = temp[j]; } } return dp[0]; // Return the count of subsequences divisible by n } const str = '1234'; const n = 4; console.log(countDivisibleSubseq(str n));
Izvade
4
Laika sarežģītība: O (len * n)
Palīgtelpa: O(n)