Open In App

Longest Common Prefix using Divide and Conquer Algorithm

Last Updated : 14 Nov, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array of strings arr[], the task is to return the longest common prefix among each and every strings present in the array. If there’s no prefix common in all the strings, return “”.

Examples:

Input: arr[] = [“geeksforgeeks”, “geeks”, “geek”, “geezer”]
Output: “gee”
Explanation: “gee” is the longest common prefix in all the given strings: “geeksforgeeks”, “geeks”, “geeks” and “geezer”.

Input: arr[] = [“apple”, “ape”, “april”]
Output : “ap”
Explanation: “ap” is the longest common prefix in all the given strings: “apple”, “ape” and “april”.

Input: arr[] = [“hello”, “world”]
Output: “”
Explanation: There’s no common prefix in the given strings.

Approach

We have discussed word by word matching and character by character matching approaches. Now, we will discuss divide and conquer approach.

The idea is simple, first divide the array of strings into two equal parts. Then find the Longest Common Prefix for all strings in each part individually using recursion. Once we got the Longest Common Prefix of both parts, the Longest Common Prefix of this array will be Longest Common Prefix of these two parts.

longest_common_prefix_using_divide_and_conquer_algorithm


C++
// C++ program to find the longest common prefix
// using Divide and Conquer Algorithm

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

// A Utility Function to find the common prefix between
// strings s1 and s2
string commonPrefixUtil(string &s1, string &s2) {
    string res;
    int n1 = s1.length(), n2 = s2.length();

    for (int i = 0; i < n1 && i < n2; i++) {
        if (s1[i] != s2[i])
            break;
        res.push_back(s1[i]);
    }

    return res;
}

// A Divide and Conquer based function to find the
// longest common prefix. This is similar to the
// merge sort technique
string commonPrefix(vector<string> &arr, int l, int r) {

    // Base Case: common prefix for a single string is
    // the string itself
    if (l == r)
        return arr[l];

    if (l < r) {
        int mid = l + (r - l) / 2;

        // Find Longest Common Prefix of first part
        string p1 = commonPrefix(arr, l, mid);

        // Find Longest Common Prefix of second part
        string p2 = commonPrefix(arr, mid + 1, r);

        // Find and return the Longest Common Prefix
        // of subarray arr[l ... r]
        return commonPrefixUtil(p1, p2);
    }
    return "";
}

string longestCommonPrefix(vector<string> &arr) {
    return commonPrefix(arr, 0, arr.size() - 1);
}

int main() {
    vector<string> arr = {"geeksforgeeks", "geeks", "geek", "geezer"};
    cout << longestCommonPrefix(arr);
    return 0;
}
Java
// Java program to find the longest common prefix
// using Divide and Conquer Algorithm

import java.util.*;

class GfG {

    // Utility function to find the common prefix between
    // strings s1 and s2
    static String commonPrefixUtil(String s1, String s2) {
        StringBuilder res = new StringBuilder();
        int n1 = s1.length(), n2 = s2.length();

        for (int i = 0; i < n1 && i < n2; i++) {
            if (s1.charAt(i) != s2.charAt(i))
                break;
            res.append(s1.charAt(i));
        }
        return res.toString();
    }

    // Divide and Conquer function to find the longest common prefix
    // This is similar to the merge sort technique
    static String commonPrefix(String[] arr, int l, int r) {
      
      	// Base Case: common prefix for a set of single string 
  		// is string itself
        if (l == r)
            return arr[l];

        if (l < r) {
            int mid = l + (r - l) / 2;
          
          	// Find Longest Common Prefix of first part
            String p1 = commonPrefix(arr, l, mid);
          
          	// Find Longest Common Prefix of second part
            String p2 = commonPrefix(arr, mid + 1, r);

          	// Find and return the Longest Common Prefix
      		// of sub array arr[l ... r]
            return commonPrefixUtil(p1, p2);
        }
        return "";
    }

    static String longestCommonPrefix(String[] arr) {
        return commonPrefix(arr, 0, arr.length - 1);
    }

    public static void main(String[] args) {
        String[] arr = {"geeksforgeeks", "geeks", "geek", "geezer"};
        System.out.println(longestCommonPrefix(arr));
    }
}
Python
# Python program to find the longest common prefix
# using Divide and Conquer Algorithm

# Utility function to find the common prefix between
# strings s1 and s2
def commonPrefixUtil(s1, s2):
    res = []
    n1, n2 = len(s1), len(s2)

    for i in range(min(n1, n2)):
        if s1[i] != s2[i]:
            break
        res.append(s1[i])
  
    return ''.join(res)

# Divide and Conquer function to find the longest common prefix
# This is similar to the merge sort technique
def commonPrefix(arr, l, r):
  
  	# Base Case: common prefix for a set of single string 
  	# is string itself
    if l == r:
        return arr[l]

    if l < r:
        mid = l + (r - l) // 2
        
        # Find Longest Common Prefix of first part
        p1 = commonPrefix(arr, l, mid)
        
        # Find Longest Common Prefix of second part
        p2 = commonPrefix(arr, mid + 1, r)

        # Find and return the Longest Common Prefix
      	# of sub array arr[l ... r]
        return commonPrefixUtil(p1, p2)
  
def longestCommonPrefix(arr):
    return commonPrefix(arr, 0, len(arr) - 1)

if __name__ == "__main__":
    arr = ["geeksforgeeks", "geeks", "geek", "geezer"]
    print(longestCommonPrefix(arr))
C#
// C# program to find the longest common prefix
// using Divide and Conquer Algorithm
using System;
using System.Collections.Generic;
using System.Text;

class GfG {

    // Utility function to find the common prefix between
    // strings s1 and s2
    static string commonPrefixUtil(string s1, string s2) {
        StringBuilder res = new StringBuilder();
        int n1 = s1.Length, n2 = s2.Length;

        for (int i = 0; i < n1 && i < n2; i++) {
            if (s1[i] != s2[i])
                break;
            res.Append(s1[i]);
        }
        return res.ToString();
    }

    // Divide and Conquer function to find the longest common prefix
    // This is similar to the merge sort technique
    static string commonPrefix(string[] arr, int l, int r) {
      
      	// Base Case: common prefix for a set of single string 
        // is string itself
        if (l == r)
            return arr[l];

        if (l < r) {
            int mid = l + (r - l) / 2;
          
          	// Find Longest Common Prefix of first part
            string p1 = commonPrefix(arr, l, mid);
          
          	// Find Longest Common Prefix of second part
            string p2 = commonPrefix(arr, mid + 1, r);

          	// Find and return the Longest Common Prefix
            // of sub array arr[l ... r]
            return commonPrefixUtil(p1, p2);
        }
        return "";
    }

    static string longestCommonPrefix(string[] arr) {
        return commonPrefix(arr, 0, arr.Length - 1);
    }

    static void Main() {
        string[] arr = {"geeksforgeeks", "geeks", "geek", "geezer"};
        Console.WriteLine(longestCommonPrefix(arr));
    }
}
JavaScript
// JavaScript program to find the longest common prefix
// using Divide and Conquer Algorithm

// Utility function to find the common prefix between
// strings s1 and s2
function commonPrefixUtil(s1, s2) {
    let res = [];
    let n1 = s1.length, n2 = s2.length;

    for (let i = 0; i < n1 && i < n2; i++) {
        if (s1[i] != s2[i])
            break;
        res.push(s1[i]);
    }
    return res.join("");
}

// Divide and Conquer function to find the longest common prefix
// This is similar to the merge sort technique
function commonPrefix(arr, l, r) {

	// Base Case: common prefix for a set of single string 
  	// is string itself
    if (l === r)
        return arr[l];

    if (l < r) {
        let mid = l + Math.floor((r - l) / 2);
        
        // Find Longest Common Prefix of first part
        let p1 = commonPrefix(arr, l, mid);
        
        // Find Longest Common Prefix of second part
        let p2 = commonPrefix(arr, mid + 1, r);
	
    	// Find and return the Longest Common Prefix
      	// of sub array arr[l ... r]
        return commonPrefixUtil(p1, p2);
    }
}

function longestCommonPrefix(arr) {
    return commonPrefix(arr, 0, arr.length - 1);
}

// Driver Code
let arr = ["geeksforgeeks", "geeks", "geek", "geezer"];
console.log(longestCommonPrefix(arr));

Output
gee

Time Complexity: O(n*m), where n is number of strings and m is length of the longest string. In the worst case, we can have n equal strings of length m, so the recurrence relation will be T(n) = 2*T(n/2) + O(m), which can be simplified to O(n*m).
Auxiliary Space: O(m), to store the longest prefix string.

Related Articles



Next Article

Similar Reads