Problem Reduction in Transform and Conquer Technique
What is Problem Reduction?
Problem reduction is an algorithm design technique that takes a complex problem and reduces it to a simpler one. The simpler problem is then solved and the solution of the simpler problem is then transformed to the solution of the original problem.
Problem reduction is a powerful technique that can be used to simplify complex problems and make them easier to solve. It can also be used to reduce the time and space complexity of algorithms.
Example:
Let’s understand the technique with the help of the following problem:
Calculate the LCM (Least Common Multiple) of two numbers X and Y.
Approach 1:
To solve the problem one can iterate through the multiples of the bigger element (say X) until that is also a multiple of the other element. This can be written as follows:
- Select the bigger element (say X here).
- Iterate through the multiples of X:
- If this is also a multiple of Y, return this as the answer.
- Otherwise, continue the traversal.
Algorithm:
Algorithm LCM(X, Y):
if Y > X:
swap X and Y
end if
for i = 1 to Y:
if X*i is divisible by Y
return X*i
end if
end for
C++
#include<bits/stdc++.h>
using namespace std;
int LCM( int x, int y) {
if (y > x) {
swap(x, y);
}
for ( int i = 1; i <= y; i++) {
if ((x*i) % y == 0) {
return i*x;
}
}
return x*y;
}
int main()
{
int x=10, y=15;
cout<<LCM(10, 15);
}
|
Java
import java.util.Scanner;
public class LCMCalculator {
static int findLCM( int x, int y) {
if (y > x) {
int temp = x;
x = y;
y = temp;
}
for ( int i = 1 ; i <= y; i++) {
if ((x * i) % y == 0 ) {
return i * x;
}
}
return x * y;
}
public static void main(String[] args) {
int x = 10 , y = 15 ;
System.out.println(findLCM(x, y));
}
}
|
Python3
def LCM(x, y):
if y > x:
x, y = y, x
for i in range ( 1 , y + 1 ):
if (x * i) % y = = 0 :
return i * x
return x * y
print (LCM( 10 , 15 ))
|
C#
using System;
public class Program
{
static int LCM( int x, int y)
{
if (y > x)
{
int temp = x;
x = y;
y = temp;
}
for ( int i = 1; i <= y; i++)
{
if ((x * i) % y == 0)
{
return i * x;
}
}
return x * y;
}
public static void Main( string [] args)
{
int x = 10, y = 15;
Console.WriteLine(LCM(x, y));
}
}
|
Javascript
function LCM(x, y) {
if (y > x) {
[x, y] = [y, x];
}
for (let i = 1; i <= y; i++) {
if ((x*i) % y === 0) {
return i*x;
}
}
return x*y;
}
console.log(LCM(10, 15));
|
Time Complexity: O(Y) as the loop can iterate for maximum Y times [because X*Y is always divisible by Y]
Auxiliary Space: O(1)
Approach 2 (Problem Reduction): The above method required a linear amount of time and if the value of Y is very big it may not be a feasible solution. This problem can be reduced to another problem which is to “calculate GCD of X and Y” and the solution of that can be transformed to get the answer to the given problem as shown below:
Algorithm:
GCD (X, Y):
if X = 0:
return Y
end if
return GCD(Y%X, X)
Algorithm LCM(X, Y):
G = GCD (X, Y)
LCM = X * Y / G
C++
#include <iostream>
int gcd( int x, int y) {
if (x == 0) {
return y;
}
return gcd(y % x, x);
}
int lcm( int x, int y) {
int g = gcd(x, y);
int lcm_result = (x * y) / g;
return lcm_result;
}
int main() {
int x = 10;
int y = 15;
std::cout << lcm(x,y);
return 0;
}
|
Java
import java.util.Scanner;
public class GCD_LCM {
static int gcd( int x, int y) {
if (x == 0 ) {
return y;
}
return gcd(y % x, x);
}
static int lcm( int x, int y) {
int g = gcd(x, y);
int lcmResult = (x * y) / g;
return lcmResult;
}
public static void main(String[] args) {
int x = 10 ;
int y = 15 ;
System.out.println(lcm(x, y));
}
}
|
Python3
def gcd(x, y):
if x = = 0 :
return y
return gcd(y % x, x)
def lcm(x, y):
g = gcd(x, y)
lcm = (x * y) / / g
return lcm
x = 10
y = 15
print (lcm(x, y))
|
C#
using System;
class Program
{
static int GCD( int x, int y)
{
if (x == 0)
{
return y;
}
return GCD(y % x, x);
}
static int LCM( int x, int y)
{
int gcd = GCD(x, y);
int lcm = (x * y) / gcd;
return lcm;
}
static void Main()
{
int x = 10;
int y = 15;
Console.WriteLine(LCM(x, y));
}
}
|
Javascript
function gcd(x, y) {
if (x === 0) {
return y;
}
return gcd(y % x, x);
}
function lcm(x, y) {
const g = gcd(x, y);
const lcm = (x * y) / g;
return lcm;
}
const x = 10;
const y = 15;
console.log(lcm(x, y));
|
Time Complexity: O(log(min(X, Y)))
Auxiliary Space: O(1)
Must Remember points about Problem Reduction:
- Reducing a problem to another one is only practical when the total time taken for transforming and solving the reduced problem is lower than solving the original problem.
- If problem A is reduced to problem B, then the lower bound of B can be higher than the lower bound of A, but it can never be lower than the lower bound of A.
Related Articles:
Last Updated :
21 Dec, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...