String Chain Formation Program in Java

In this article, we will solve the String Chain Formation problem, where we need to determine whether we can arrange a given array of strings in such a way that the last character of one string matches the first character of the next. This problem is commonly encountered in word puzzles, graph theory, and algorithmic challenges. We will explore an efficient graph-based approach and an alternative sorting-based method to check for a valid chain formation.

Understanding the Problem

Given an array of strings, determine whether it is possible to arrange them in a sequence such that the last character of one string matches the first character of the next string.

Example

Explanation:

  • "apple" ends with 'e', and "elephant" starts with 'e'.
  • "elephant" ends with 't', and "tiger" starts with 't'.
  • "tiger" ends with 'r', and "rat" starts with 'r'.
  • Since all words connect, a valid chain is possible.

Approach to Solve the Problem

  1. Build character mappings:
    • Store first and last characters of each word.
    • Use a HashMap to count occurrences of each starting and ending letter.
  2. Check Eulerian Path conditions:
    • A valid path exists if at most one character has +1 difference in start and end counts.
  3. Try forming a sequence using backtracking (DFS or Graph approach).

Java Implementation – Using Graph (Optimal Approach)

package com.javacodepoint.stringarray;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class StringChainFormation {

    // Method to check if the given words can form a valid chain
    public static boolean canFormStringChain(String[] words) {
        Map<Character, Integer> inDegree = new HashMap<>();
        Map<Character, Integer> outDegree = new HashMap<>();
        Map<Character, List<String>> adjacencyList = new HashMap<>();
        Set<Character> uniqueChars = new HashSet<>();

        // Build graph representation
        for (String word : words) {
            char first = word.charAt(0);
            char last = word.charAt(word.length() - 1);
            
            outDegree.put(first, outDegree.getOrDefault(first, 0) + 1);
            inDegree.put(last, inDegree.getOrDefault(last, 0) + 1);

            adjacencyList.computeIfAbsent(first, k -> new ArrayList<>()).add(word);
            uniqueChars.add(first);
            uniqueChars.add(last);
        }

        // Check Eulerian Path conditions
        int startCount = 0, endCount = 0;
        for (char c : uniqueChars) {
            int in = inDegree.getOrDefault(c, 0);
            int out = outDegree.getOrDefault(c, 0);

            if (out - in == 1) {
                startCount++;
            } else if (in - out == 1) {
                endCount++;
            } else if (in != out) {
                return false;
            }
        }

        return (startCount == 1 && endCount == 1) || (startCount == 0 && endCount == 0);
    }

    public static void main(String[] args) {
        String[] words = {"apple", "elephant", "tiger", "rat"};

        if (canFormStringChain(words)) {
            System.out.println("Yes, the words can form a valid chain.");
        } else {
            System.out.println("No, a valid chain cannot be formed.");
        }
    }
}

Explanation of the Code

  1. Build a character frequency map:
    • Track how many times each character appears at the start and end of words.
    • Store adjacency lists of words grouped by their first letter.
  2. Check Eulerian Path conditions:
    • At most one character should have +1 outgoing edge.
    • At most one character should have +1 incoming edge.
    • All other characters should have equal in-degree and out-degree.
  3. Return true if conditions match, otherwise return false.

Alternative Approach: Using Simple Sorting (Less Efficient)

import java.util.Arrays;

public class SimpleStringChain {

    public static boolean canArrangeStrings(String[] words) {
        Arrays.sort(words); // Sort alphabetically (not always correct but helps)
        
        for (int i = 0; i < words.length - 1; i++) {
            if (words[i].charAt(words[i].length() - 1) != words[i + 1].charAt(0)) {
                return false; // Break if chain rule is not satisfied
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String[] words = {"apple", "elephant", "tiger", "rat"};

        if (canArrangeStrings(words)) {
            System.out.println("Yes, a valid chain can be formed.");
        } else {
            System.out.println("No, a valid chain cannot be formed.");
        }
    }
}

Conclusion

This problem is closely related to Eulerian Path in Graph Theory, where we check incoming and outgoing edges to determine if a path exists.

You can learn the Top 20 string array programs for interview preparation (Click here).

Java logical programs list


Java Basic Programs

Java String Programs

Java String Array Programs

Java Miscellaneous Programs

Java Programs based on the Collection Framework

Leave a Reply

Your email address will not be published. Required fields are marked *