Apple | Phone Interview | Group rotated strings
Anonymous User
3759

Given a list of strings, group the strings that are equivalent when rotated. For example, the input
["abc", "bca", "cab", "xyz", "yzx", "cba", "aaaa"]
should return the groups:
{["abc", "bca", "cab"], ["xyz, "yzx"], ["cba"], ["aaaa"]}

The order of the strings or the groups for the result does not matter.
{["cba"], ["xyz, "yzx"], ["bca", "abc", "cab"], ["aaaa"]}
is an acceptable solution too.

Knew how to find if one string is a rotated version of the other but couldn't piece out how to put in the common group. Another approach which I preferred is to generate hash of string and seems that is a wrong approach. Any inputs on how to approach for this problem?

Skeleton:

public class GroupRotatedStrings
{

	public static void main(String[] args)
	{
		List<String> input = Arrays.asList("abc", "bca", "cab", "xyz", "yzx", "cba", "aaaa");
		List<List<String>> groups = groupRotatedStrings(input);
		System.out.println(groups);
	}

	public static List<List<String>> groupRotatedStrings(List<String> strings)
	{
		return v1(strings);
//		return v2(strings);
	}

	private static List<List<String>> v1(List<String> strings)
	{
		for (int i = 0; i < strings.size(); i++)
		{
			String s1 = strings.get(i);
			for (int j = i+1; j < strings.size(); j++)
			{
				String s2 = strings.get(j);
				System.out.println(s1 + " " + s2 + " " + isRotatedVersion(s1, s2));
			}
		}
		
		return new ArrayList<>();
	}

	private static List<List<String>> v2(List<String> strings)
	{
		Map<String, List<String>> group = new HashMap<>();
		for(String s : strings)
			group.compute(genHash(s), (k, v) -> v == null ? new ArrayList<>() : v).add(s);
		
		return new ArrayList<>(group.values());
	}

	/*
	 * Wrong method of hashing the string.
	 */
	private static String genHash(String s)
	{
		if(s.length() == 0 || s == null)
			return null;
		
		/*
		 * abc => a-b + b-c + c-a + (a + b + c)
		 * bca => b-c + c-a + a-b + (b + c + a)
		 * cba => c-b + b-a + a-c + (c + b + a) => should not be the same hashcode
		 */
		char prev = s.charAt(0);
		char curr = 0;
		int sum = prev;
		int sumDiff = 0;
		for(int i = 1; i < s.length(); i++)
		{
			curr = s.charAt(i);
			sumDiff += (prev - curr);
			sum += curr;
			prev = curr;
		}
		
		if(s.length() > 1)
		{
			sumDiff += (curr - s.charAt(0));
		}
		
		
		return String.valueOf(sum + sumDiff);
	}
	
	private static boolean isRotatedVersion(String s1, String s2)
	{
		if(s1 == null)
			return s1 == s2;
		
		if(s1.length() != s2.length())
			return false;
		
		return (s1 + s1).contains(s2);
	}
	

}

Start with a brute force approach and then try to optimize the algorithm with a better run time complexity.

Comments (8)