Given two given numbers a and b where 1 ≤ a ≤ b, find the perfect cubes between a and b (a and b inclusive). The function returns -1 if there is no proper cube between the given values.
Examples:
Input: a = 1, b = 100
Output: [1, 8, 27, 64]
Explanation: These are the proper cubes between 1 and 100.Input: a = 24, b = 576
Output: [27, 64, 125, 216, 343, 512]
Explanation: These are the proper cubes between 24 and 576.
Table of Content
[Naive Approach] Check Every Number for Perfect Cube - O((b - a + 1) × ∛b) Time and O(1) Space
The idea is to iterate through every number from a to b. For each number, try all possible cube roots and check whether their cube equals the current number. If yes, add it to the answer.
Working of Approach:
- Traverse every number from a to b.
- For each number, try all possible cube roots.
- If i³ equals the current number, it is a perfect cube.
- Store all such numbers in the answer.
- Return [-1] if no cube is found.
#include <iostream>
#include <vector>
using namespace std;
vector<int> properCubes(int a, int b)
{
vector<int> res;
// Check every number in the range
for (int num = a; num <= b; num++)
{
// Try all possible cube roots
for (int i = 1; i * i * i <= num; i++)
{
// If current number is a perfect cube
if (i * i * i == num)
{
res.push_back(num);
break;
}
}
}
// Return {-1} if no cube exists
if (res.empty())
res.push_back(-1);
return res;
}
int main()
{
int a = 24, b = 576;
vector<int> res = properCubes(a, b);
cout << "[";
for (int i = 0; i < res.size(); i++)
{
cout << res[i];
if (i != res.size() - 1)
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> properCubes(int a, int b)
{
ArrayList<Integer> res = new ArrayList<>();
// Check every number in the range
for (int num = a; num <= b; num++) {
// Try all possible cube roots
for (int i = 1; i * i * i <= num; i++) {
// If current number is a perfect cube
if (i * i * i == num) {
res.add(num);
break;
}
}
}
// Return {-1} if no cube exists
if (res.isEmpty())
res.add(-1);
return res;
}
public static void main(String[] args)
{
int a = 24, b = 576;
ArrayList<Integer> res = properCubes(a, b);
System.out.print("[");
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i));
if (i != res.size() - 1)
System.out.print(", ");
}
System.out.println("]");
}
}
def properCubes(a, b):
res = []
# Check every number in the range
for num in range(a, b + 1):
# Try all possible cube roots
i = 1
while i * i * i <= num:
# If current number is a perfect cube
if i * i * i == num:
res.append(num)
break
i += 1
# Return [-1] if no cube exists
if not res:
res.append(-1)
return res
if __name__ == "__main__":
a, b = 24, 576
res = properCubes(a, b)
print(res)
using System;
using System.Collections.Generic;
class GFG {
static List<int> properCubes(int a, int b)
{
List<int> res = new List<int>();
// Check every number in the range
for (int num = a; num <= b; num++) {
// Try all possible cube roots
for (int i = 1; i * i * i <= num; i++) {
// If current number is a perfect cube
if (i * i * i == num) {
res.Add(num);
break;
}
}
}
// Return {-1} if no cube exists
if (res.Count == 0)
res.Add(-1);
return res;
}
static void Main()
{
int a = 24, b = 576;
List<int> res = properCubes(a, b);
Console.Write("[");
for (int i = 0; i < res.Count; i++) {
Console.Write(res[i]);
if (i != res.Count - 1)
Console.Write(", ");
}
Console.WriteLine("]");
}
}
function properCubes(a, b)
{
let res = [];
// Check every number in the range
for (let num = a; num <= b; num++) {
// Try all possible cube roots
for (let i = 1; i * i * i <= num; i++) {
// If current number is a perfect cube
if (i * i * i === num) {
res.push(num);
break;
}
}
}
// Return {-1} if no cube exists
if (res.length === 0)
res.push(-1);
return res;
}
// Driver Code
let a = 24, b = 576;
let res = properCubes(a, b);
console.log("[" + res.join(", ") + "]");
Output
[27, 64, 125, 216, 343, 512]
[Expected Approach] Using Cube Root Range - O(∛b - ∛a + 1) Time and O(1) Space
The idea is to use the cube roots of a and b to find the possible range of cube roots. Then, generate cubes only within this range and collect those lying in [a, b].
Working of Approach:
- Compute the cube roots of a and b.
- Iterate only through the possible cube roots.
- Generate the cube of each integer.
- Store cubes that lie in [a, b].
- Return [-1] if no cube is found.
Let us understand with an example:
Input: a = 24, b = 576
- Compute the cube root range: start = floor(cbrt(24)) = 2, end = floor(cbrt(576)) = 8.
- Iterate from i = 2 to i = 9 (end + 1) to safely handle floating-point rounding.
- Generate cubes: 8, 27, 64, 125, 216, 343, 512, 729.
- Keep only the cubes that lie in the range [24, 576]: 27, 64, 125, 216, 343, 512.
- Return [27, 64, 125, 216, 343, 512].
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
vector<int> properCubes(int a, int b)
{
int start = cbrt(a);
int end = cbrt(b);
vector<int> res;
// Generate cubes only in the required range
for (int i = start; i <= end + 1; i++)
{
int cube = i * i * i;
// Add cube if it lies in the range
if (cube >= a && cube <= b)
res.push_back(cube);
}
// Return {-1} if no cube exists
if (res.empty())
res.push_back(-1);
return res;
}
int main()
{
int a = 24, b = 576;
vector<int> res = properCubes(a, b);
cout << "[";
for (int i = 0; i < res.size(); i++)
{
cout << res[i];
if (i != res.size() - 1)
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> properCubes(int a, int b)
{
int start = (int)Math.cbrt(a);
int end = (int)Math.cbrt(b);
ArrayList<Integer> res = new ArrayList<>();
// Generate cubes only in the required range
for (int i = start; i <= end + 1; i++) {
int cube = i * i * i;
// Add cube if it lies in the range
if (cube >= a && cube <= b)
res.add(cube);
}
// Return {-1} if no cube exists
if (res.isEmpty())
res.add(-1);
return res;
}
public static void main(String[] args)
{
int a = 24, b = 576;
ArrayList<Integer> res = properCubes(a, b);
System.out.print("[");
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i));
if (i != res.size() - 1)
System.out.print(", ");
}
System.out.println("]");
}
}
import math
def properCubes(a, b):
start = int(math.cbrt(a))
end = int(math.cbrt(b))
res = []
# Generate cubes only in the required range
for i in range(start, end + 2):
cube = i * i * i
# Add cube if it lies in the range
if cube >= a and cube <= b:
res.append(cube)
# Return {-1} if no cube exists
if not res:
res.append(-1)
return res
if __name__ == '__main__':
a = 24
b = 576
res = properCubes(a, b)
print('[', end='')
for i in range(len(res)):
print(res[i], end='')
if i != len(res) - 1:
print(', ', end='')
print(']')
using System;
using System.Collections.Generic;
class GFG {
static List<int> properCubes(int a, int b)
{
int start = (int)Math.Cbrt(a);
int end = (int)Math.Cbrt(b);
List<int> res = new List<int>();
// Generate cubes only in the required range
for (int i = start; i <= end + 1; i++) {
int cube = i * i * i;
// Add cube if it lies in the range
if (cube >= a && cube <= b)
res.Add(cube);
}
// Return {-1} if no cube exists
if (res.Count == 0)
res.Add(-1);
return res;
}
static void Main()
{
int a = 24, b = 576;
List<int> res = properCubes(a, b);
Console.Write("[");
for (int i = 0; i < res.Count; i++) {
Console.Write(res[i]);
if (i != res.Count - 1)
Console.Write(", ");
}
Console.WriteLine("]");
}
}
function properCubes(a, b)
{
let start = Math.cbrt(a);
let end = Math.cbrt(b);
let res = [];
// Generate cubes only in the required range
for (let i = Math.ceil(start); i <= Math.floor(end) + 1;
i++) {
let cube = i * i * i;
// Add cube if it lies in the range
if (cube >= a && cube <= b)
res.push(cube);
}
// Return {-1} if no cube exists
if (res.length === 0)
res.push(-1);
return res;
}
// Driver Code
let a = 24, b = 576;
let res = properCubes(a, b);
console.log("[" + res.join(", ") + "]");
Output
[27, 64, 125, 216, 343, 512]