Given a large positive integer represented as a string s, count all of its rotations that are divisible by 4. A rotation of a number is obtained by moving some digits from the beginning to the end. For example, rotations of 1234 are 1234, 2341, 3412, and 4123.
Note: A number with a leading zero after rotation (for example, 04) is not considered a valid number and hence should not be counted.
Examples:
Input: s = "8"
Output: 1
Explanation: 8 is divisible by 4.Input: s = "20"
Output: 1
Explanation: 20 is divisible by 4 but after rotation, 02 is not divisible by 4.Input: s = "43292816"
Output: 5
Explanation: The valid rotations divisible by 4 are 43292816, 92816432, 81643292, 16432928, and 32928164. Hence, the answer is 5.
Table of Content
[Naive Approach] By Generating Every Rotation - O(n ^ 2) Time and O(n) Space
The idea is to generate every possible rotation of the given number. Ignore rotations that start with 0, as they are invalid. For each valid rotation, check whether its last two digits form a number divisible by 4, since a number is divisible by 4 if and only if its last two digits are divisible by 4.
- Generate all n rotations of the given string.
- Skip the rotation if it starts with '0'.
- Extract the last two digits of the rotation.
- Check if the two-digit number is divisible by 4.
- Count all such valid rotations and return the count.
#include <bits/stdc++.h>
using namespace std;
// Returns the count of all valid rotations that are divisible by 4.
int countRotations(string &s)
{
int n = s.size();
int cnt = 0;
// Handle the single-digit case.
if (n == 1)
return ((s[0] - '0') % 4 == 0);
// Generate every possible rotation.
for (int i = 0; i < n; i++)
{
// Form the current rotation.
string rotation = s.substr(i) + s.substr(0, i);
// Rotations with leading zeros are invalid.
if (rotation[0] == '0')
continue;
// A number is divisible by 4 if its last two digits are.
int len = rotation.size();
int twoDigit = (rotation[len - 2] - '0') * 10 + (rotation[len - 1] - '0');
if (twoDigit % 4 == 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
int main()
{
string s = "43292816";
cout << countRotations(s);
return 0;
}
import java.util.*;
class GFG {
// Returns the count of all valid rotations that are
// divisible by 4.
static int countRotations(String s)
{
int n = s.length();
int cnt = 0;
// Handle the single-digit case.
if (n == 1)
return ((s.charAt(0) - '0') % 4 == 0) ? 1 : 0;
// Generate every possible rotation.
for (int i = 0; i < n; i++) {
// Form the current rotation.
String rotation
= s.substring(i) + s.substring(0, i);
// Rotations with leading zeros are invalid.
if (rotation.charAt(0) == '0')
continue;
// A number is divisible by 4 if its last two
// digits are.
int len = rotation.length();
int twoDigit
= (rotation.charAt(len - 2) - '0') * 10
+ (rotation.charAt(len - 1) - '0');
if (twoDigit % 4 == 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
public static void main(String[] args)
{
String s = "43292816";
System.out.println(countRotations(s));
}
}
# Returns the count of all valid rotations that are divisible by 4.
def countRotations(s):
n = len(s)
cnt = 0
# Handle the single-digit case.
if n == 1:
return 1 if int(s[0]) % 4 == 0 else 0
# Generate every possible rotation.
for i in range(n):
# Form the current rotation.
rotation = s[i:] + s[:i]
# Rotations with leading zeros are invalid.
if rotation[0] == '0':
continue
# A number is divisible by 4 if its last two digits are.
length = len(rotation)
twoDigit = int(rotation[length - 2]) * 10 + int(rotation[length - 1])
if twoDigit % 4 == 0:
cnt += 1
# Return the number of valid rotations.
return cnt
# Driver Code
if __name__ == "__main__":
s = "43292816"
print(countRotations(s))
using System;
class GFG {
// Returns the count of all valid rotations that are
// divisible by 4.
static int countRotations(string s)
{
int n = s.Length;
int cnt = 0;
// Handle the single-digit case.
if (n == 1)
return ((s[0] - '0') % 4 == 0) ? 1 : 0;
// Generate every possible rotation.
for (int i = 0; i < n; i++) {
// Form the current rotation.
string rotation
= s.Substring(i) + s.Substring(0, i);
// Rotations with leading zeros are invalid.
if (rotation[0] == '0')
continue;
// A number is divisible by 4 if its last two
// digits are.
int len = rotation.Length;
int twoDigit = (rotation[len - 2] - '0') * 10
+ (rotation[len - 1] - '0');
if (twoDigit % 4 == 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
static void Main()
{
string s = "43292816";
Console.WriteLine(countRotations(s));
}
}
// Returns the count of all valid rotations that are
// divisible by 4.
function countRotations(s)
{
let n = s.length;
let cnt = 0;
// Handle the single-digit case.
if (n === 1)
return (parseInt(s[0]) % 4 === 0) ? 1 : 0;
// Generate every possible rotation.
for (let i = 0; i < n; i++) {
// Form the current rotation.
let rotation = s.slice(i) + s.slice(0, i);
// Rotations with leading zeros are invalid.
if (rotation[0] === "0")
continue;
// A number is divisible by 4 if its last two
// digits are.
let len = rotation.length;
let twoDigit = parseInt(rotation[len - 2]) * 10
+ parseInt(rotation[len - 1]);
if (twoDigit % 4 === 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
let s = "43292816";
console.log(countRotations(s));
Output
5
[Expected Approach] Using Circular Indexing - O(n) Time and O(1) Space
Instead of generating every rotation, observe that a number is divisible by 4 if its last two digits are divisible by 4. Using circular indexing, we can directly determine the last two digits of each rotation and check its divisibility in constant time, avoiding the need to construct the rotated string.
- Handle the single-digit case separately.
- Consider each index as the starting position of a rotation.
- Skip the rotation if it starts with '0'.
- Form the last two digits using the two digits immediately before the starting index in a circular manner.
- If the two-digit number is divisible by 4, increment the count.
- Return the total count of valid rotations.
#include <bits/stdc++.h>
using namespace std;
// Returns the count of all valid rotations that are divisible by 4.
int countRotations(string &s)
{
int n = s.size();
int cnt = 0;
// Handle the single-digit case.
if (n == 1)
return (s[0] - '0') % 4 == 0;
// Check every possible rotation.
for (int i = 0; i < n; i++)
{
// Rotations with leading zeros are invalid.
if (s[i] == '0')
continue;
// Compute the last two digits of the current rotation.
int twoDigit = (s[(i + n - 2) % n] - '0') * 10 + (s[(i + n - 1) % n] - '0');
// A number is divisible by 4 if its last two digits are.
if (twoDigit % 4 == 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
int main()
{
string s = "43292816";
cout << countRotations(s);
return 0;
}
import java.util.*;
class GFG {
// Returns the count of all valid rotations that are
// divisible by 4.
static int countRotations(String s)
{
int n = s.length();
int cnt = 0;
// Handle the single-digit case.
if (n == 1)
return ((s.charAt(0) - '0') % 4 == 0) ? 1 : 0;
// Check every possible rotation.
for (int i = 0; i < n; i++) {
// Rotations with leading zeros are invalid.
if (s.charAt(i) == '0')
continue;
// Compute the last two digits of the current
// rotation.
int twoDigit
= (s.charAt((i + n - 2) % n) - '0') * 10
+ (s.charAt((i + n - 1) % n) - '0');
// A number is divisible by 4 if its last two
// digits are.
if (twoDigit % 4 == 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
public static void main(String[] args)
{
String s = "43292816";
System.out.println(countRotations(s));
}
}
# Returns the count of all valid rotations that are divisible by 4.
def countRotations(s):
n = len(s)
cnt = 0
# Handle the single-digit case.
if n == 1:
return 1 if int(s[0]) % 4 == 0 else 0
# Check every possible rotation.
for i in range(n):
# Rotations with leading zeros are invalid.
if s[i] == '0':
continue
# Compute the last two digits of the current rotation.
twoDigit = int(s[(i + n - 2) % n]) * 10 + int(s[(i + n - 1) % n])
# A number is divisible by 4 if its last two digits are.
if twoDigit % 4 == 0:
cnt += 1
# Return the number of valid rotations.
return cnt
# Driver Code
if __name__ == "__main__":
s = "43292816"
print(countRotations(s))
using System;
class GFG {
// Returns the count of all valid rotations that are
// divisible by 4.
static int countRotations(string s)
{
int n = s.Length;
int cnt = 0;
// Handle the single-digit case.
if (n == 1)
return ((s[0] - '0') % 4 == 0) ? 1 : 0;
// Check every possible rotation.
for (int i = 0; i < n; i++) {
// Rotations with leading zeros are invalid.
if (s[i] == '0')
continue;
// Compute the last two digits of the current
// rotation.
int twoDigit = (s[(i + n - 2) % n] - '0') * 10
+ (s[(i + n - 1) % n] - '0');
// A number is divisible by 4 if its last two
// digits are.
if (twoDigit % 4 == 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
static void Main()
{
string s = "43292816";
Console.WriteLine(countRotations(s));
}
}
// Returns the count of all valid rotations that are
// divisible by 4.
function countRotations(s)
{
let n = s.length;
let cnt = 0;
// Handle the single-digit case.
if (n === 1)
return (parseInt(s[0]) % 4 === 0) ? 1 : 0;
// Check every possible rotation.
for (let i = 0; i < n; i++) {
// Rotations with leading zeros are invalid.
if (s[i] === "0")
continue;
// Compute the last two digits of the current
// rotation.
let twoDigit = parseInt(s[(i + n - 2) % n]) * 10
+ parseInt(s[(i + n - 1) % n]);
// A number is divisible by 4 if its last two digits
// are.
if (twoDigit % 4 === 0)
cnt++;
}
// Return the number of valid rotations.
return cnt;
}
// Driver Code
let s = "43292816";
console.log(countRotations(s));
Output
5