Open In App

Instance Simplification Method in Transform and Conquer Technique

Instance simplification is one of the Transform and Conquer techniques. To understand Instance Simplification, first let us understand what is transform and conquer.

Transform and Conquer is a technique whose main idea is to transfer the problem into some easier or similar versions using some procedure and then solve that easier or simpler versions and combine those versions to get the solution of the actual one. The design consists of two parts: 

There are three ways to do that:

  1. Instance simplification: a technique of simplifying the problem to more convenient or simpler instances.
  2. Representation change: the data structure is transformed to represent the problem more efficiently.
  3. Problem reduction: the problem can be transformed to an easier problem to solve

Example:

Let us understand the Instance simplification in a better way with the help of an example: 

Consider the problem of finding a unique element in a given array

Approach 1: To solve this problem, one can compare each element with all other elements and find out the unique elements. 

It can be written as follows:

Algorithm:

Algorithm unique_element( A[1. . . n]:
        for i=1 to n-1
                temp = A[i]
                for j = i+1 to n:
                        temp1 = A[j]
                        if(temp == temp1) then
                                print 'element is not unique'
                        end if
                end for
        end for

Below is the implementation of the above approach:

#include <iostream>
#include <vector>
using namespace std;

// Function to find all unique elements in the array
void findAllUniqueElements(vector<int>& arr)
{
    int n = arr.size();
    bool isUnique;
    // Loop through each element in the array
    for (int i = 0; i < n; i++) {
        isUnique = true;
        // Compare the current element with all other
        // elements
        for (int j = 0; j < n; j++) {
            // If a duplicate is found, mark isUnique as
            // false and break the loop
            if (i != j && arr[i] == arr[j]) {
                isUnique = false;
                break;
            }
        }
        // If no duplicate is found, print the unique
        // element
        if (isUnique) {
            cout << "Unique element is: " << arr[i] << endl;
        }
    }
}

int main()
{
    // Define an array with some elements
    vector<int> arr = { 1, 2, 3, 2, 1 };
    // Call the function to find all unique elements
    findAllUniqueElements(arr);
    return 0;
}
import java.util.ArrayList;

public class Main {
    // Function to find all unique elements in the array
    static void
    findAllUniqueElements(ArrayList<Integer> arr)
    {
        int n = arr.size();
        boolean isUnique;
        // Loop through each element in the array
        for (int i = 0; i < n; i++) {
            isUnique = true;
            // Compare the current element with all other
            // elements
            for (int j = 0; j < n; j++) {
                // If a duplicate is found, mark isUnique as
                // false and break the loop
                if (i != j
                    && arr.get(i).equals(arr.get(j))) {
                    isUnique = false;
                    break;
                }
            }
            // If no duplicate is found, print the unique
            // element
            if (isUnique) {
                System.out.println("Unique element is: "
                                   + arr.get(i));
            }
        }
    }

    public static void main(String[] args)
    {
        // Define an ArrayList with some elements
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(2);
        arr.add(1);
        // Call the function to find all unique elements
        findAllUniqueElements(arr);
    }
}
# Function to find all unique elements in the array
def find_all_unique_elements(arr):
    n = len(arr)
    # Loop through each element in the array
    for i in range(n):
        is_unique = True
        # Compare the current element with all other elements
        for j in range(n):
            # If a duplicate is found, mark is_unique as False and break the loop
            if i != j and arr[i] == arr[j]:
                is_unique = False
                break
        # If no duplicate is found, print the unique element
        if is_unique:
            print("Unique element is:", arr[i])


# Driver code
if __name__ == "__main__":
    # Define a list with some elements
    arr = [1, 2, 3, 2, 1]
    # Call the function to find all unique elements
    find_all_unique_elements(arr)
// Function to find all unique elements in the array
function findAllUniqueElements(arr) {
    let n = arr.length;
    let isUnique;
    // Loop through each element in the array
    for(let i=0; i<n; i++) {
        isUnique = true;
        // Compare the current element with all other elements
        for(let j=0; j<n; j++) {
            // If a duplicate is found, mark isUnique as false and break the loop
            if(i != j && arr[i] == arr[j]) {
                isUnique = false;
                break;
            }
        }
        // If no duplicate is found, print the unique element
        if(isUnique) {
            console.log("Unique element is: " + arr[i]);
        }
    }
}

let arr = [1, 2, 3, 2, 1];
findAllUniqueElements(arr);

Output
Unique element is: 3


Time Complexity: O(N2) as the algorithm involves nested loops
Auxiliary Space: O(1)

Approach 2 (Instance Simplification): The above mentioned approach was complex in the sense of comparisons. It requires a lot of comparisons which can be reduced or converted to a simpler version as shown below. 

  • To identify the unique element, one can first apply any sorting technique and sort all the elements. This step is called presorting. 
  • The advantage of presorting here is that for further steps, only the adjacent elements will have to be checked, instead of looking for the element in the entire array.

This is the simplification of instance where there is lesser comparison for a single element.

The approach is as follows:

Algorithm:

Algorithm unique_element(A[1. . . n]):
        Sort (A[])
        for i = 1 to n - 1 
                temp = A[i]
                temp1 = A[i + 1]
                if(temp == temp1) then
                        print 'element is not unique'
                end if
       end for

Complexity Analysis: 

Time Complexity: O(N * logN)
Auxiliary Space: O(1)

Thus the effectiveness of the algorithm is determined by the quality of the sorting algorithm used. Even though not much is gained in terms of time complexity, the advantage of this algorithm lies in the convenience of checking only the adjacent elements.  

Advantages: The advantages of the instance simplification method are mentioned below:

Article Tags :