Given a collection of strings, can we make all the strings equal - algorithm

The allowed operations are removal of character from a string and adding that character to another string. We can repeat the operation as many times as we want.
Given list = ['CAA', 'CBB'].
We can remove 'A' from the first string and add it to the second string.
'CA', 'CBBA'.
Now, we can remove 'B" from the second string and add in the middle of string 'CA'.
So, we have 'CBA' and 'CBA'

Step-1. Compute the frequency of each character in all the strings of the list, let's say it as stringList.
Step-2: Compute the length of stringList and let's call it as length. (length is equal to the number of strings in the list.)
Step-3: Now, for the frequency of each character, Check if it is divisible by length. If any frequency is not divisible by length then it's not possible to equate the strings.
If it is possible:
Just distribute the characters equally among the strings to get an answer list.

Related

Number of possible palindrome anagrams for a given word

I have to find No. of palindrome anagrams are possible for a given word.
Suppose the word is aaabbbb.My approach is
Prepare a hash map that contains no. of time each letter is appearing
For my example it will be
a--->3
b--->4
If length of string is even then no. of occurrence of each letter should be even to form palindrome of given word else no of
palindrome anagrams is 0
If length of string is odd then at max one occurrence of letter can be odd and other should be even.
This two above steps was for finding that weather a given word can can form palindrome or not.
Now for finding no of palindrome anagrams, what approach should I follow?
First thing to notice is that if the word is an odd length, then there must be exactly one character with an odd number of occurrences. If the word is an even length, then there must be no characters with an odd number of occurrences. In either case, you're looking for how many ways you can arrange the pairs of characters. You're looking for the number of permutations since order matters:
n = number of character pairs (aaaabbb would have 3 pairs, aabbcccc would have 4 pairs)
(n)!/( number_of_a_pairs! * number_of_b_pairs! * etc..)
So in the aaaabbb case, you're finding the permutations of aab:
3!/2!1! = 3
baa = baabaab
aba = abababa
aab = aabbbaa
And in the aabbcccc case, you're finding the permutations of abcc:
4!/2! = 12:
abcc
acbc
accb
bacc
bcac
bcca
cabc
cacb
cbac
cbca
ccab
ccba

Using dynamic programming to count the number of permutations

I have a string A of length N. I have to find number of strings (B) of length N that have M (M<=N) same characters as string A but satisfies the condition that A[i]!=B[i] for all i. Assume the characters that have to be same and the different ones are also given. What will be the recurrence relation to find number of such strings?
Example
123 is string A and M=1, and the character which is same is '1', and the new characters are '4' and '5'. The valid permutations are 451, 415, 514, 541. So it is a sort of derangement of 1 item of the given 3.
I am able to find the answer using inclusion-exclusion principle but wanted to know whether there is a recurrence relation to do the same?
Let us call g(M,N) the number of permutations satisfying your condition.
If M is 0, then the answer is N!
Otherwise, M>0 and consider placing the first character that is in string A.
There are M important positions corresponding to the places in the string where we are not allowed to place a certain character.
If we put our first character in one of these (M-1) important places (we cannot put it in position 1 due to the restriction), then we must take the place of one of the restricted characters, and so the number of restrictions reduces by 2 (1 for the character we place, and 1 for the character whose position we occupied).
If we put our first character in one of the N-M unimportant places, then we have only reduced the number of restrictions by 1.
Therefore the recurrence relation is:
g(M,N)=(M-1)g(M-2,N-1)+(N-M)g(M-1,N-1) if M>0
=N! if M=0
For your example, we wish to calculate g(1,3) (1 character matches, total of 3 characters placed)
g(1,3)=(3-1)g(0,2)
=(3-1).2!
=4

Algorithm to find

the logic behind this was (n-2)3^(n-3) has lots of repetitons like (abc)***(abc) when abc is at start and at end and the strings repated total to 3^4 . similarly as abc moves ahead and number of sets of (abc) increase
You can use dynamic programming to compute the number of forbidden strings.
The algorithms follow from the observation below:
"Legal string of size n is the legal string of size n - 1 extended with one letter, so that the last three letters of the resulting string are not all distinct."
So if we had all the legal strings of size n-1 we could try extending them to obtain the legal strings of size n.
To check whether the extended string is legal we just need to know the last two letters of the previous string (of size n-1).
In the algorithm we will compute two arrays, where
different[i] # number of legal strings of length i in which last two letters are different
same[i] # number of legal strings of length i in which last two letters are the same
It can be easily proved that:
different[i+1] = different[i] + 2*same[i]
same[i+1] = different[i] + same[i]
It is the consequence of the following facts:
Any 'same' string of size i+1 can be obtained either from 'same' string of size i (think BB -> BBB) or from 'different' string (think AB -> ABB) and these are the only options.
Any 'different' string of size i+1 can be obtained either from 'different' string of size i (think AB-> ABA ) or from the 'same' string in two ways (AA -> AAB or AA -> AAC)
Having observed all this it is easy to write an algorithm that computes the result in O(n) time.
I suggest you use recursion, and look at two numbers:
F(n), the number of legal strings of length n whose last two symbols are the same.
G(n), the number of legal strings of length n whose last two symbols are different.
Is that enough to go on?
get the ASCII values of the last three letters and add the square values of these letters. If it gives a certain result, then it is forbidden. For A, B and C, it would be fine.
To do this:
1) find out how to get characters from your string.
2) find out how to get ASCII value of a character.
3) Multiply these ASCII values with themselves.
4) Do that for the three letters each time and add their values.

If a word is made up of two valid words

Given a dictionary find out if given word can be made by two words in dictionary. For eg. given "newspaper" you have to find if it can be made by two words. (news and paper in this case). Only thing i can think of is starting from beginning and checking if current string is a word. In this case checking n, ne, new, news..... check for the remaining part if current string is a valid word.
Also how do you generalize it for k(means if a word is made up of k words) ? Any thoughts?
Starting your split at the center may yield results faster. For example, for newspaper, you would first try splitting at 'news paper' or 'newsp aper'. As you can see, for this example, you would find your result on the first or second try. If you do not find a result, just search outwards. See the example for 'crossbow' below:
cros sbow
cro ssbow
cross bow
For the case with two words, the problem can be solved by just considering all possible ways of splitting the word into two, then checking each half to see if it's a valid word. If the input string has length n, then there are only O(n) different ways of splitting the string. If you store the strings in a structure supporting fast lookup (say, a trie, or hash table).
The more interesting case is when you have k > 2 words to split the word into. For this, we can use a really elegant recursive formulation:
A word can be split into k words if it can be split into a word followed by a word splittable into k - 1 words.
The recursive base case would be that a word can be split into zero words only if it's the empty string, which is trivially true.
To use this recursive insight, we'll modify the original algorithm by considering all possible splits of the word into two parts. Once we have that split, we can check if the first part of the split is a word and if the second part of the split can be broken apart into k - 1 words. As an optimization, we don't recurse on all possible splits, but rather just on those where we know the first word is valid. Here's some sample code written in Java:
public static boolean isSplittable(String word, int k, Set<String> dictionary) {
/* Base case: If the string is empty, we can only split into k words and vice-
* versa.
*/
if (word.isEmpty() || k == 0)
return word.isEmpty() && k == 0;
/* Generate all possible non-empty splits of the word into two parts, recursing on
* problems where the first word is known to be valid.
*
* This loop is structured so that we always try pulling off at least one letter
* from the input string so that we don't try splitting the word into k pieces
* of which some are empty.
*/
for (int i = 1; i <= word.length(); ++i) {
String first = word.substring(0, i), last = word.substring(i);
if (dictionary.contains(first) &&
isSplittable(last, k - 1, dictionary)
return true;
}
/* If we're here, then no possible split works in this case and we should signal
* that no solution exists.
*/
return false;
}
}
This code, in the worst case, runs in time O(nk) because it tries to generate all possible partitions of the string into k different pieces. Of course, it's unlikely to hit this worst-case behavior because most possible splits won't end up forming any words.
I'd first loop through the dictionary using a strpos(-like) function to check if it occurs at all. Then try if you can find a match with the results.
So it would do something like this:
Loop through the dictionary strpos-ing every word in the dictionary and saving results into an array, let's say it gives me the results 'new', 'paper', and 'news'.
Check if new+paper==newspaper, check if new+news==newspaper, etc, untill you get to paper+news==newspaper which returns.
Not sure if it is a good method though, but it seems more efficient than checking a word letter for letter (more iterations) and you didn't explain how you'd check when the second word started.
Don't know what you mean by 'how do you generalize it for k'.

Algorithm to Generate Alphabetic String That is Alphabetically Between Two Other Strings?

A problem I'm trying to solve: given that you have two distinct strings composed of the lower case letters a through z, find a string between the two strings such that further in-between strings can always be found.
Further detail:
Given that 'a' comes before 'b' alphabetically, there are an infinite number of strings between 'a' and 'b', when sorted as a dictionary would: 'aa', 'aaa', 'aaaa', 'ab', 'aba', etc. However, there are not an infinite number of strings between all strings - nothing comes between 'a' and 'aa'. Further, between 'a' and 'aaa' there exists only one in-between string 'aa'.
What is an algorithm that can find a string X that comes alphabetically between 'a' and 'b' that also satisfies the condition that there are infinite number of strings between 'a' and X as well as X and 'b'?
assuming that one can insert an infinite number of strings between the two strings.
If the lower string is shorter, add as many 'a's as to make the lengths equal then add a 'b' to the middle string. If the upper word is shorter make the middle string equal the lower string and append z to the middle string. If the two strings have equal length, use either method.
You have stated everything you need to know to find a solution. Basically, a finite number of strings exist only if one string is a prefix of the other and the rest is a string of "a"s.
Otherwise, you can find an infinite number of in-between strings.

Resources