Efficient/Fast way to get permutation of a String in java [duplicate] - java
What is an elegant way to find all the permutations of a string. E.g. permutation for ba, would be ba and ab, but what about longer string such as abcdefgh? Is there any Java implementation example?
public static void permutation(String str) {
permutation("", str);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0) System.out.println(prefix);
else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
(via Introduction to Programming in Java)
Use recursion.
Try each of the letters in turn as the first letter and then find all the permutations of the remaining letters using a recursive call.
The base case is when the input is an empty string the only permutation is the empty string.
Here is my solution that is based on the idea of the book "Cracking the Coding Interview" (P54):
/**
* List permutations of a string.
*
* #param s the input string
* #return the list of permutations
*/
public static ArrayList<String> permutation(String s) {
// The result
ArrayList<String> res = new ArrayList<String>();
// If input string's length is 1, return {s}
if (s.length() == 1) {
res.add(s);
} else if (s.length() > 1) {
int lastIndex = s.length() - 1;
// Find out the last character
String last = s.substring(lastIndex);
// Rest of the string
String rest = s.substring(0, lastIndex);
// Perform permutation on the rest string and
// merge with the last character
res = merge(permutation(rest), last);
}
return res;
}
/**
* #param list a result of permutation, e.g. {"ab", "ba"}
* #param c the last character
* #return a merged new list, e.g. {"cab", "acb" ... }
*/
public static ArrayList<String> merge(ArrayList<String> list, String c) {
ArrayList<String> res = new ArrayList<>();
// Loop through all the string in the list
for (String s : list) {
// For each string, insert the last character to all possible positions
// and add them to the new list
for (int i = 0; i <= s.length(); ++i) {
String ps = new StringBuffer(s).insert(i, c).toString();
res.add(ps);
}
}
return res;
}
Running output of string "abcd":
Step 1: Merge [a] and b:
[ba, ab]
Step 2: Merge [ba, ab] and c:
[cba, bca, bac, cab, acb, abc]
Step 3: Merge [cba, bca, bac, cab, acb, abc] and d:
[dcba, cdba, cbda, cbad, dbca, bdca, bcda, bcad, dbac, bdac, badc, bacd, dcab, cdab, cadb, cabd, dacb, adcb, acdb, acbd, dabc, adbc, abdc, abcd]
Of all the solutions given here and in other forums, I liked Mark Byers the most. That description actually made me think and code it myself.
Too bad I cannot voteup his solution as I am newbie.
Anyways here is my implementation of his description
public class PermTest {
public static void main(String[] args) throws Exception {
String str = "abcdef";
StringBuffer strBuf = new StringBuffer(str);
doPerm(strBuf,0);
}
private static void doPerm(StringBuffer str, int index){
if(index == str.length())
System.out.println(str);
else { //recursively solve this by placing all other chars at current first pos
doPerm(str, index+1);
for (int i = index+1; i < str.length(); i++) {//start swapping all other chars with current first char
swap(str,index, i);
doPerm(str, index+1);
swap(str,i, index);//restore back my string buffer
}
}
}
private static void swap(StringBuffer str, int pos1, int pos2){
char t1 = str.charAt(pos1);
str.setCharAt(pos1, str.charAt(pos2));
str.setCharAt(pos2, t1);
}
}
I prefer this solution ahead of the first one in this thread because this solution uses StringBuffer. I wouldn't say my solution doesn't create any temporary string (it actually does in system.out.println where the toString() of StringBuffer is called). But I just feel this is better than the first solution where too many string literals are created. May be some performance guy out there can evalute this in terms of 'memory' (for 'time' it already lags due to that extra 'swap')
A very basic solution in Java is to use recursion + Set ( to avoid repetitions ) if you want to store and return the solution strings :
public static Set<String> generatePerm(String input)
{
Set<String> set = new HashSet<String>();
if (input == "")
return set;
Character a = input.charAt(0);
if (input.length() > 1)
{
input = input.substring(1);
Set<String> permSet = generatePerm(input);
for (String x : permSet)
{
for (int i = 0; i <= x.length(); i++)
{
set.add(x.substring(0, i) + a + x.substring(i));
}
}
}
else
{
set.add(a + "");
}
return set;
}
All the previous contributors have done a great job explaining and providing the code. I thought I should share this approach too because it might help someone too. The solution is based on (heaps' algorithm )
Couple of things:
Notice the last item which is depicted in the excel is just for helping you better visualize the logic. So, the actual values in the last column would be 2,1,0 (if we were to run the code because we are dealing with arrays and arrays start with 0).
The swapping algorithm happens based on even or odd values of current position. It's very self explanatory if you look at where the swap method is getting called.You can see what's going on.
Here is what happens:
public static void main(String[] args) {
String ourword = "abc";
String[] ourArray = ourword.split("");
permute(ourArray, ourArray.length);
}
private static void swap(String[] ourarray, int right, int left) {
String temp = ourarray[right];
ourarray[right] = ourarray[left];
ourarray[left] = temp;
}
public static void permute(String[] ourArray, int currentPosition) {
if (currentPosition == 1) {
System.out.println(Arrays.toString(ourArray));
} else {
for (int i = 0; i < currentPosition; i++) {
// subtract one from the last position (here is where you are
// selecting the the next last item
permute(ourArray, currentPosition - 1);
// if it's odd position
if (currentPosition % 2 == 1) {
swap(ourArray, 0, currentPosition - 1);
} else {
swap(ourArray, i, currentPosition - 1);
}
}
}
}
Let's use input abc as an example.
Start off with just the last element (c) in a set (["c"]), then add the second last element (b) to its front, end and every possible positions in the middle, making it ["bc", "cb"] and then in the same manner it will add the next element from the back (a) to each string in the set making it:
"a" + "bc" = ["abc", "bac", "bca"] and "a" + "cb" = ["acb" ,"cab", "cba"]
Thus entire permutation:
["abc", "bac", "bca","acb" ,"cab", "cba"]
Code:
public class Test
{
static Set<String> permutations;
static Set<String> result = new HashSet<String>();
public static Set<String> permutation(String string) {
permutations = new HashSet<String>();
int n = string.length();
for (int i = n - 1; i >= 0; i--)
{
shuffle(string.charAt(i));
}
return permutations;
}
private static void shuffle(char c) {
if (permutations.size() == 0) {
permutations.add(String.valueOf(c));
} else {
Iterator<String> it = permutations.iterator();
for (int i = 0; i < permutations.size(); i++) {
String temp1;
for (; it.hasNext();) {
temp1 = it.next();
for (int k = 0; k < temp1.length() + 1; k += 1) {
StringBuilder sb = new StringBuilder(temp1);
sb.insert(k, c);
result.add(sb.toString());
}
}
}
permutations = result;
//'result' has to be refreshed so that in next run it doesn't contain stale values.
result = new HashSet<String>();
}
}
public static void main(String[] args) {
Set<String> result = permutation("abc");
System.out.println("\nThere are total of " + result.size() + " permutations:");
Iterator<String> it = result.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
This one is without recursion
public static void permute(String s) {
if(null==s || s.isEmpty()) {
return;
}
// List containing words formed in each iteration
List<String> strings = new LinkedList<String>();
strings.add(String.valueOf(s.charAt(0))); // add the first element to the list
// Temp list that holds the set of strings for
// appending the current character to all position in each word in the original list
List<String> tempList = new LinkedList<String>();
for(int i=1; i< s.length(); i++) {
for(int j=0; j<strings.size(); j++) {
tempList.addAll(merge(s.charAt(i), strings.get(j)));
}
strings.removeAll(strings);
strings.addAll(tempList);
tempList.removeAll(tempList);
}
for(int i=0; i<strings.size(); i++) {
System.out.println(strings.get(i));
}
}
/**
* helper method that appends the given character at each position in the given string
* and returns a set of such modified strings
* - set removes duplicates if any(in case a character is repeated)
*/
private static Set<String> merge(Character c, String s) {
if(s==null || s.isEmpty()) {
return null;
}
int len = s.length();
StringBuilder sb = new StringBuilder();
Set<String> list = new HashSet<String>();
for(int i=0; i<= len; i++) {
sb = new StringBuilder();
sb.append(s.substring(0, i) + c + s.substring(i, len));
list.add(sb.toString());
}
return list;
}
Well here is an elegant, non-recursive, O(n!) solution:
public static StringBuilder[] permutations(String s) {
if (s.length() == 0)
return null;
int length = fact(s.length());
StringBuilder[] sb = new StringBuilder[length];
for (int i = 0; i < length; i++) {
sb[i] = new StringBuilder();
}
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
int times = length / (i + 1);
for (int j = 0; j < times; j++) {
for (int k = 0; k < length / times; k++) {
sb[j * length / times + k].insert(k, ch);
}
}
}
return sb;
}
One of the simple solution could be just keep swapping the characters recursively using two pointers.
public static void main(String[] args)
{
String str="abcdefgh";
perm(str);
}
public static void perm(String str)
{ char[] char_arr=str.toCharArray();
helper(char_arr,0);
}
public static void helper(char[] char_arr, int i)
{
if(i==char_arr.length-1)
{
// print the shuffled string
String str="";
for(int j=0; j<char_arr.length; j++)
{
str=str+char_arr[j];
}
System.out.println(str);
}
else
{
for(int j=i; j<char_arr.length; j++)
{
char tmp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = tmp;
helper(char_arr,i+1);
char tmp1 = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = tmp1;
}
}
}
python implementation
def getPermutation(s, prefix=''):
if len(s) == 0:
print prefix
for i in range(len(s)):
getPermutation(s[0:i]+s[i+1:len(s)],prefix+s[i] )
getPermutation('abcd','')
This is what I did through basic understanding of Permutations and Recursive function calling. Takes a bit of time but it's done independently.
public class LexicographicPermutations {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="abc";
List<String>combinations=new ArrayList<String>();
combinations=permutations(s);
Collections.sort(combinations);
System.out.println(combinations);
}
private static List<String> permutations(String s) {
// TODO Auto-generated method stub
List<String>combinations=new ArrayList<String>();
if(s.length()==1){
combinations.add(s);
}
else{
for(int i=0;i<s.length();i++){
List<String>temp=permutations(s.substring(0, i)+s.substring(i+1));
for (String string : temp) {
combinations.add(s.charAt(i)+string);
}
}
}
return combinations;
}}
which generates Output as [abc, acb, bac, bca, cab, cba].
Basic logic behind it is
For each character, consider it as 1st character & find the combinations of remaining characters. e.g. [abc](Combination of abc)->.
a->[bc](a x Combination of (bc))->{abc,acb}
b->[ac](b x Combination of (ac))->{bac,bca}
c->[ab](c x Combination of (ab))->{cab,cba}
And then recursively calling each [bc],[ac] & [ab] independently.
Use recursion.
when the input is an empty string the only permutation is an empty string.Try for each of the letters in the string by making it as the first letter and then find all the permutations of the remaining letters using a recursive call.
import java.util.ArrayList;
import java.util.List;
class Permutation {
private static List<String> permutation(String prefix, String str) {
List<String> permutations = new ArrayList<>();
int n = str.length();
if (n == 0) {
permutations.add(prefix);
} else {
for (int i = 0; i < n; i++) {
permutations.addAll(permutation(prefix + str.charAt(i), str.substring(i + 1, n) + str.substring(0, i)));
}
}
return permutations;
}
public static void main(String[] args) {
List<String> perms = permutation("", "abcd");
String[] array = new String[perms.size()];
for (int i = 0; i < perms.size(); i++) {
array[i] = perms.get(i);
}
int x = array.length;
for (final String anArray : array) {
System.out.println(anArray);
}
}
}
this worked for me..
import java.util.Arrays;
public class StringPermutations{
public static void main(String args[]) {
String inputString = "ABC";
permute(inputString.toCharArray(), 0, inputString.length()-1);
}
public static void permute(char[] ary, int startIndex, int endIndex) {
if(startIndex == endIndex){
System.out.println(String.valueOf(ary));
}else{
for(int i=startIndex;i<=endIndex;i++) {
swap(ary, startIndex, i );
permute(ary, startIndex+1, endIndex);
swap(ary, startIndex, i );
}
}
}
public static void swap(char[] ary, int x, int y) {
char temp = ary[x];
ary[x] = ary[y];
ary[y] = temp;
}
}
Java implementation without recursion
public Set<String> permutate(String s){
Queue<String> permutations = new LinkedList<String>();
Set<String> v = new HashSet<String>();
permutations.add(s);
while(permutations.size()!=0){
String str = permutations.poll();
if(!v.contains(str)){
v.add(str);
for(int i = 0;i<str.length();i++){
String c = String.valueOf(str.charAt(i));
permutations.add(str.substring(i+1) + c + str.substring(0,i));
}
}
}
return v;
}
Let me try to tackle this problem with Kotlin:
fun <T> List<T>.permutations(): List<List<T>> {
//escape case
if (this.isEmpty()) return emptyList()
if (this.size == 1) return listOf(this)
if (this.size == 2) return listOf(listOf(this.first(), this.last()), listOf(this.last(), this.first()))
//recursive case
return this.flatMap { lastItem ->
this.minus(lastItem).permutations().map { it.plus(lastItem) }
}
}
Core concept: Break down long list into smaller list + recursion
Long answer with example list [1, 2, 3, 4]:
Even for a list of 4 it already kinda get's confusing trying to list all the possible permutations in your head, and what we need to do is exactly to avoid that. It is easy for us to understand how to make all permutations of list of size 0, 1, and 2, so all we need to do is break them down to any of those sizes and combine them back up correctly. Imagine a jackpot machine: this algorithm will start spinning from the right to the left, and write down
return empty/list of 1 when list size is 0 or 1
handle when list size is 2 (e.g. [3, 4]), and generate the 2 permutations ([3, 4] & [4, 3])
For each item, mark that as the last in the last, and find all the permutations for the rest of the item in the list. (e.g. put [4] on the table, and throw [1, 2, 3] into permutation again)
Now with all permutation it's children, put itself back to the end of the list (e.g.: [1, 2, 3][,4], [1, 3, 2][,4], [2, 3, 1][, 4], ...)
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class hello {
public static void main(String[] args) throws IOException {
hello h = new hello();
h.printcomp();
}
int fact=1;
public void factrec(int a,int k){
if(a>=k)
{fact=fact*k;
k++;
factrec(a,k);
}
else
{System.out.println("The string will have "+fact+" permutations");
}
}
public void printcomp(){
String str;
int k;
Scanner in = new Scanner(System.in);
System.out.println("enter the string whose permutations has to b found");
str=in.next();
k=str.length();
factrec(k,1);
String[] arr =new String[fact];
char[] array = str.toCharArray();
while(p<fact)
printcomprec(k,array,arr);
// if incase u need array containing all the permutation use this
//for(int d=0;d<fact;d++)
//System.out.println(arr[d]);
}
int y=1;
int p = 0;
int g=1;
int z = 0;
public void printcomprec(int k,char array[],String arr[]){
for (int l = 0; l < k; l++) {
for (int b=0;b<k-1;b++){
for (int i=1; i<k-g; i++) {
char temp;
String stri = "";
temp = array[i];
array[i] = array[i + g];
array[i + g] = temp;
for (int j = 0; j < k; j++)
stri += array[j];
arr[z] = stri;
System.out.println(arr[z] + " " + p++);
z++;
}
}
char temp;
temp=array[0];
array[0]=array[y];
array[y]=temp;
if (y >= k-1)
y=y-(k-1);
else
y++;
}
if (g >= k-1)
g=1;
else
g++;
}
}
/** Returns an array list containing all
* permutations of the characters in s. */
public static ArrayList<String> permute(String s) {
ArrayList<String> perms = new ArrayList<>();
int slen = s.length();
if (slen > 0) {
// Add the first character from s to the perms array list.
perms.add(Character.toString(s.charAt(0)));
// Repeat for all additional characters in s.
for (int i = 1; i < slen; ++i) {
// Get the next character from s.
char c = s.charAt(i);
// For each of the strings currently in perms do the following:
int size = perms.size();
for (int j = 0; j < size; ++j) {
// 1. remove the string
String p = perms.remove(0);
int plen = p.length();
// 2. Add plen + 1 new strings to perms. Each new string
// consists of the removed string with the character c
// inserted into it at a unique location.
for (int k = 0; k <= plen; ++k) {
perms.add(p.substring(0, k) + c + p.substring(k));
}
}
}
}
return perms;
}
Here is a straightforward minimalist recursive solution in Java:
public static ArrayList<String> permutations(String s) {
ArrayList<String> out = new ArrayList<String>();
if (s.length() == 1) {
out.add(s);
return out;
}
char first = s.charAt(0);
String rest = s.substring(1);
for (String permutation : permutations(rest)) {
out.addAll(insertAtAllPositions(first, permutation));
}
return out;
}
public static ArrayList<String> insertAtAllPositions(char ch, String s) {
ArrayList<String> out = new ArrayList<String>();
for (int i = 0; i <= s.length(); ++i) {
String inserted = s.substring(0, i) + ch + s.substring(i);
out.add(inserted);
}
return out;
}
We can use factorial to find how many strings started with particular letter.
Example: take the input abcd. (3!) == 6 strings will start with every letter of abcd.
static public int facts(int x){
int sum = 1;
for (int i = 1; i < x; i++) {
sum *= (i+1);
}
return sum;
}
public static void permutation(String str) {
char[] str2 = str.toCharArray();
int n = str2.length;
int permutation = 0;
if (n == 1) {
System.out.println(str2[0]);
} else if (n == 2) {
System.out.println(str2[0] + "" + str2[1]);
System.out.println(str2[1] + "" + str2[0]);
} else {
for (int i = 0; i < n; i++) {
if (true) {
char[] str3 = str.toCharArray();
char temp = str3[i];
str3[i] = str3[0];
str3[0] = temp;
str2 = str3;
}
for (int j = 1, count = 0; count < facts(n-1); j++, count++) {
if (j != n-1) {
char temp1 = str2[j+1];
str2[j+1] = str2[j];
str2[j] = temp1;
} else {
char temp1 = str2[n-1];
str2[n-1] = str2[1];
str2[1] = temp1;
j = 1;
} // end of else block
permutation++;
System.out.print("permutation " + permutation + " is -> ");
for (int k = 0; k < n; k++) {
System.out.print(str2[k]);
} // end of loop k
System.out.println();
} // end of loop j
} // end of loop i
}
}
//insert each character into an arraylist
static ArrayList al = new ArrayList();
private static void findPermutation (String str){
for (int k = 0; k < str.length(); k++) {
addOneChar(str.charAt(k));
}
}
//insert one char into ArrayList
private static void addOneChar(char ch){
String lastPerStr;
String tempStr;
ArrayList locAl = new ArrayList();
for (int i = 0; i < al.size(); i ++ ){
lastPerStr = al.get(i).toString();
//System.out.println("lastPerStr: " + lastPerStr);
for (int j = 0; j <= lastPerStr.length(); j++) {
tempStr = lastPerStr.substring(0,j) + ch +
lastPerStr.substring(j, lastPerStr.length());
locAl.add(tempStr);
//System.out.println("tempStr: " + tempStr);
}
}
if(al.isEmpty()){
al.add(ch);
} else {
al.clear();
al = locAl;
}
}
private static void printArrayList(ArrayList al){
for (int i = 0; i < al.size(); i++) {
System.out.print(al.get(i) + " ");
}
}
//Rotate and create words beginning with all letter possible and push to stack 1
//Read from stack1 and for each word create words with other letters at the next location by rotation and so on
/* eg : man
1. push1 - man, anm, nma
2. pop1 - nma , push2 - nam,nma
pop1 - anm , push2 - amn,anm
pop1 - man , push2 - mna,man
*/
public class StringPermute {
static String str;
static String word;
static int top1 = -1;
static int top2 = -1;
static String[] stringArray1;
static String[] stringArray2;
static int strlength = 0;
public static void main(String[] args) throws IOException {
System.out.println("Enter String : ");
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bfr = new BufferedReader(isr);
str = bfr.readLine();
word = str;
strlength = str.length();
int n = 1;
for (int i = 1; i <= strlength; i++) {
n = n * i;
}
stringArray1 = new String[n];
stringArray2 = new String[n];
push(word, 1);
doPermute();
display();
}
public static void push(String word, int x) {
if (x == 1)
stringArray1[++top1] = word;
else
stringArray2[++top2] = word;
}
public static String pop(int x) {
if (x == 1)
return stringArray1[top1--];
else
return stringArray2[top2--];
}
public static void doPermute() {
for (int j = strlength; j >= 2; j--)
popper(j);
}
public static void popper(int length) {
// pop from stack1 , rotate each word n times and push to stack 2
if (top1 > -1) {
while (top1 > -1) {
word = pop(1);
for (int j = 0; j < length; j++) {
rotate(length);
push(word, 2);
}
}
}
// pop from stack2 , rotate each word n times w.r.t position and push to
// stack 1
else {
while (top2 > -1) {
word = pop(2);
for (int j = 0; j < length; j++) {
rotate(length);
push(word, 1);
}
}
}
}
public static void rotate(int position) {
char[] charstring = new char[100];
for (int j = 0; j < word.length(); j++)
charstring[j] = word.charAt(j);
int startpos = strlength - position;
char temp = charstring[startpos];
for (int i = startpos; i < strlength - 1; i++) {
charstring[i] = charstring[i + 1];
}
charstring[strlength - 1] = temp;
word = new String(charstring).trim();
}
public static void display() {
int top;
if (top1 > -1) {
while (top1 > -1)
System.out.println(stringArray1[top1--]);
} else {
while (top2 > -1)
System.out.println(stringArray2[top2--]);
}
}
}
Another simple way is to loop through the string, pick the character that is not used yet and put it to a buffer, continue the loop till the buffer size equals to the string length. I like this back tracking solution better because:
Easy to understand
Easy to avoid duplication
The output is sorted
Here is the java code:
List<String> permute(String str) {
if (str == null) {
return null;
}
char[] chars = str.toCharArray();
boolean[] used = new boolean[chars.length];
List<String> res = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
Arrays.sort(chars);
helper(chars, used, sb, res);
return res;
}
void helper(char[] chars, boolean[] used, StringBuilder sb, List<String> res) {
if (sb.length() == chars.length) {
res.add(sb.toString());
return;
}
for (int i = 0; i < chars.length; i++) {
// avoid duplicates
if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
continue;
}
// pick the character that has not used yet
if (!used[i]) {
used[i] = true;
sb.append(chars[i]);
helper(chars, used, sb, res);
// back tracking
sb.deleteCharAt(sb.length() - 1);
used[i] = false;
}
}
}
Input str: 1231
Output list: {1123, 1132, 1213, 1231, 1312, 1321, 2113, 2131, 2311, 3112, 3121, 3211}
Noticed that the output is sorted, and there is no duplicate result.
Recursion is not necessary, even you can calculate any permutation directly, this solution uses generics to permute any array.
Here is a good information about this algorihtm.
For C# developers here is more useful implementation.
public static void main(String[] args) {
String word = "12345";
Character[] array = ArrayUtils.toObject(word.toCharArray());
long[] factorials = Permutation.getFactorials(array.length + 1);
for (long i = 0; i < factorials[array.length]; i++) {
Character[] permutation = Permutation.<Character>getPermutation(i, array, factorials);
printPermutation(permutation);
}
}
private static void printPermutation(Character[] permutation) {
for (int i = 0; i < permutation.length; i++) {
System.out.print(permutation[i]);
}
System.out.println();
}
This algorithm has O(N) time and space complexity to calculate each permutation.
public class Permutation {
public static <T> T[] getPermutation(long permutationNumber, T[] array, long[] factorials) {
int[] sequence = generateSequence(permutationNumber, array.length - 1, factorials);
T[] permutation = generatePermutation(array, sequence);
return permutation;
}
public static <T> T[] generatePermutation(T[] array, int[] sequence) {
T[] clone = array.clone();
for (int i = 0; i < clone.length - 1; i++) {
swap(clone, i, i + sequence[i]);
}
return clone;
}
private static int[] generateSequence(long permutationNumber, int size, long[] factorials) {
int[] sequence = new int[size];
for (int j = 0; j < sequence.length; j++) {
long factorial = factorials[sequence.length - j];
sequence[j] = (int) (permutationNumber / factorial);
permutationNumber = (int) (permutationNumber % factorial);
}
return sequence;
}
private static <T> void swap(T[] array, int i, int j) {
T t = array[i];
array[i] = array[j];
array[j] = t;
}
public static long[] getFactorials(int length) {
long[] factorials = new long[length];
long factor = 1;
for (int i = 0; i < length; i++) {
factor *= i <= 1 ? 1 : i;
factorials[i] = factor;
}
return factorials;
}
}
My implementation based on Mark Byers's description above:
static Set<String> permutations(String str){
if (str.isEmpty()){
return Collections.singleton(str);
}else{
Set <String> set = new HashSet<>();
for (int i=0; i<str.length(); i++)
for (String s : permutations(str.substring(0, i) + str.substring(i+1)))
set.add(str.charAt(i) + s);
return set;
}
}
Permutation of String:
public static void main(String args[]) {
permu(0,"ABCD");
}
static void permu(int fixed,String s) {
char[] chr=s.toCharArray();
if(fixed==s.length())
System.out.println(s);
for(int i=fixed;i<s.length();i++) {
char c=chr[i];
chr[i]=chr[fixed];
chr[fixed]=c;
permu(fixed+1,new String(chr));
}
}
Here is another simpler method of doing Permutation of a string.
public class Solution4 {
public static void main(String[] args) {
String a = "Protijayi";
per(a, 0);
}
static void per(String a , int start ) {
//bse case;
if(a.length() == start) {System.out.println(a);}
char[] ca = a.toCharArray();
//swap
for (int i = start; i < ca.length; i++) {
char t = ca[i];
ca[i] = ca[start];
ca[start] = t;
per(new String(ca),start+1);
}
}//per
}
A java implementation to print all the permutations of a given string considering duplicate characters and prints only unique characters is as follow:
import java.util.Set;
import java.util.HashSet;
public class PrintAllPermutations2
{
public static void main(String[] args)
{
String str = "AAC";
PrintAllPermutations2 permutation = new PrintAllPermutations2();
Set<String> uniqueStrings = new HashSet<>();
permutation.permute("", str, uniqueStrings);
}
void permute(String prefixString, String s, Set<String> set)
{
int n = s.length();
if(n == 0)
{
if(!set.contains(prefixString))
{
System.out.println(prefixString);
set.add(prefixString);
}
}
else
{
for(int i=0; i<n; i++)
{
permute(prefixString + s.charAt(i), s.substring(0,i) + s.substring(i+1,n), set);
}
}
}
}
String permutaions using Es6
Using reduce() method
const permutations = str => {
if (str.length <= 2)
return str.length === 2 ? [str, str[1] + str[0]] : [str];
return str
.split('')
.reduce(
(acc, letter, index) =>
acc.concat(permutations(str.slice(0, index) + str.slice(index + 1)).map(val => letter + val)),
[]
);
};
console.log(permutations('STR'));
In case anyone wants to generate the permutations to do something with them, instead of just printing them via a void method:
static List<int[]> permutations(int n) {
class Perm {
private final List<int[]> permutations = new ArrayList<>();
private void perm(int[] array, int step) {
if (step == 1) permutations.add(array.clone());
else for (int i = 0; i < step; i++) {
perm(array, step - 1);
int j = (step % 2 == 0) ? i : 0;
swap(array, step - 1, j);
}
}
private void swap(int[] array, int i, int j) {
int buffer = array[i];
array[i] = array[j];
array[j] = buffer;
}
}
int[] nVector = new int[n];
for (int i = 0; i < n; i++) nVector [i] = i;
Perm perm = new Perm();
perm.perm(nVector, n);
return perm.permutations;
}
Related
Is there a way to iterate through an array without using loops?
I'm trying to write a code that will output all possible passwords from a given array recursively, e.g. given the input "ab" will output the next: a b aa ab ba bb the problem is that I'm instructed to use only one loop in the crack() function below and that's it. I cannot use any other functions, just those two. This is what I've got so far: import java.util.*; public class PasswordGen { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("Please enter a string:"); char array[] = sc.next().toCharArray(); System.out.println("All Combination:"); crack(array); sc.close(); } static void crack(char[] array) { for (int i = 1; i <= array.length; i++) { generate(array, i, "", array.length); } } static void generate(char[] array, int i, String string, int length) { //recursion stopping if condition is meet if (i == 0) { System.out.println(string); return; } for (int j = 0; j < length; j++) { String charArray = string + array[j]; generate(array, i -1, charArray , length); } return; } } Is there a way to get the same output without using the for loop in the generate() function? (see code below). static void generate(char[] array, int i, String string, int length) { //recursion stopping if condition is meet if (i == 0) { System.out.println(string); return; } for (int j = 0; j < length; j++) { String charArray = string + array[j]; generate(array, i -1, charArray , length); } Any suggestions/better way to do it?
Not sure if this answers your question, but here is a class that does what you want without any for loop: import java.util.*; import java.util.stream.*; class Bruteforcer { private List<Integer> state = Collections.singletonList(0); private final String allowedChars; private final Integer maxLength; public Bruteforcer(String allowedChars, Integer maxLength){ assert allowedChars != null; assert allowedChars.length() > 0; assert maxLength > 0; this.allowedChars = allowedChars; this.maxLength = maxLength; } public String next(){ final var allIndexesAreLastChar = this.state.stream().allMatch(i -> i == this.allowedChars.length() - 1); final var currentLength = this.state.size(); if (currentLength > this.maxLength){ return null; } final var nextPassword = this.state.stream() .map(i -> this.allowedChars.substring(i, i + 1)) .collect(Collectors.joining("")); if (allIndexesAreLastChar){ this.state = Collections.nCopies(currentLength + 1, 0); return nextPassword; } this.state = IntStream.range(0, currentLength) .mapToObj(i -> { final var current = this.state.get(currentLength - 1 - i); final var mustIncrement = i == 0 || this.state.get(currentLength - i) == this.allowedChars.length() - 1; if (mustIncrement){ return current == this.allowedChars.length() - 1 ? 0 : current + 1; } return current; }) .collect(Collectors.toList()); Collections.reverse(this.state); return nextPassword; } } class FindPasswordApplication { public static void main(String[] args) { final var bruteforcer = new Bruteforcer("ab", 2); for (var i = 0; i < 10; i ++){ final var password = bruteforcer.next(); System.out.println(password); } } }
Maximum Repeating characters and count
I wanted to get the maximum repeating characters count and its relevant index. I am able to print the max repeating characters in a given string and its index. However I am unable to print the total count of repeating character. Below is my code public class MaxRepeating { static char charactercountIndex(String str) { int len = str.length(); int count = 0; char res = str.charAt(0); for (int i = 0; i < len; i++) { int cur_count = 0; for (int j = i + 1; j < len; j++) { if (str.charAt(i) != str.charAt(j)) break; cur_count++; } if (cur_count > count) { count = cur_count; res = str.charAt(i); } } return res; } public static void main(String args[]) { String str = "aaaaaaccde"; char s1 = charactercountIndex(str); str.indexOf(s1); System.out.println(str.indexOf(s1)); System.out.println(charactercountIndex(str)); } } output should <0,6> 0 is the index of character a 6 is the total time character "a" present in the string
If you are open to a slightly different approach, there is a fairly straightforward way to do this using regex and streams. We can try splitting the input string into like-lettered substring components using the following regex: (?<=(.))(?!\\1) Then, we can use Collections.max to find the largest string in the collection, and finally use String#indexOf to find the index of that substring. String str = "aaaabbddddddddddddddddddddaaccde"; List<String> parts = Arrays.asList(str.split("(?<=(.))(?!\\1)")); String max = Collections.max(parts, Comparator.comparing(s -> s.length())); System.out.println("largest substring: " + max); int index = str.indexOf(max); System.out.println("index of largest substring: " + index); largest substring: dddddddddddddddddddd index of largest substring: 6
I've done something like this: static Entry<String, Integer> charactercountIndex(String str) { HashMap<String, Integer> stringIntegerHashMap = new HashMap<>(); for (String letter : str.split("")) { if (stringIntegerHashMap.containsKey(letter)) { stringIntegerHashMap.put(letter, (stringIntegerHashMap.get(letter) + 1)); } else { stringIntegerHashMap.put(letter, 1); } } Entry<String, Integer> maxEntry = null; for (Entry<String, Integer> entry : stringIntegerHashMap.entrySet()) { if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) { maxEntry = entry; } } return maxEntry; } public static void main(String args[]) { String str = "aaaabbddddddddddddddddddddaaccde"; Entry<String, Integer> s1 = charactercountIndex(str); System.out.println(s1.getKey()); System.out.println(s1.getValue()); } If you have any trouble, let me know.
You can return the result through a local class instance (which contains both the character and its occurrences). I added a local class CountResult. By the way, I fixed your code (see // including ... comment). You can try and check the working code below here. public class MaxRepeating { private static CountResult charactercountIndex(String str) { int len = str.length(); char res = str.charAt(0); int count = 0; for (int i = 0; i < len; i++) { int cur_count = 1; // including the tested char (first occurence) for (int j = i + 1; j < len; j++) { if (str.charAt(i) != str.charAt(j)) break; cur_count++; } if (cur_count > count) { res = str.charAt(i); count = cur_count; } } return new CountResult(res, count); } private static class CountResult { private char maxChar; private int count; public CountResult(char maxChar, int count) { this.maxChar = maxChar; this.count = count; } public String toString() { return String.format("<" + maxChar + "," + count + ">"); } } public static void main(String args[]) { String str = "aaaaaaccde"; System.out.println(charactercountIndex(str)); } }
You can create your own class that you will not be bounded to count of returned parameters from method. public class MyCharacter { private static int count; private static char character; private static int indexOf; public void characterCountIndex(String str) { int len = str.length(); for (int i = 0; i < len; i++) { int cur_count = 1; for (int j = i + 1; j < len; j++) { if (str.charAt(i) != str.charAt(j)) break; cur_count++; } if (cur_count > count) { count = cur_count; character = str.charAt(i); indexOf = str.indexOf(character); } } } #Override public String toString() { return String.format("<%d, %d>", indexOf, count); } public static void main(String[] args) { String str = "aaaaaaccde"; MyCharacter myCharacter = new MyCharacter(); myCharacter.characterCountIndex(str); System.out.println(myCharacter); } }
How to reverse String in place in Java
How to reverse String in place in Java input String : 1234 Output Should : 4321 what i have tried. public static void main(String args[]) { String number = "1234"; System.out.println("original String: " + number); String reversed = inPlaceReverse(number); System.out.println("reversed String: " + reversed); } public static String inPlaceReverse(final String input) { final StringBuilder builder = new StringBuilder(input); int length = builder.length(); for (int i = 0; i < length / 2; i++) { final char current = builder.charAt(i); final int otherEnd = length - i - 1; builder.setCharAt(i, builder.charAt(otherEnd)); // swap builder.setCharAt(otherEnd, current); } return builder.toString(); } i am getting answer like: reversed String: 4231 as i expected 4321.
If your teacher wants to see your work then you should manipulate the chars directly. Something like the following should be enough to let you spot the mistake: public static String reverse(String orig) { char[] s = orig.toCharArray(); final int n = s.length; final int halfLength = n / 2; for (int i=0; i<halfLength; i++) { char temp = s[i]; s[i] = s[n-1-i]; s[n-1-i] = temp; } return new String(s); }
It can be even simpler using StringBuilder's reverse() function: public static String inPlaceReverse(String input) { StringBuilder builder = new StringBuilder(input); return builder.reverse().toString(); }
public static String inPlaceReverse(String number) { char[] ch = number.toCharArray(); int i = 0; int j = number.length()-1; while (i < j) { char temp = ch[i]; ch[i] = ch[j]; ch[j] = temp; i++; j--; } return String.valueOf(ch); }
1. Using Character Array: public String reverseSting(String inputString) { char[] inputStringArray = inputString.toCharArray(); String reverseString = ""; for (int i = inputStringArray.length - 1; i >= 0; i--) { reverseString += inputStringArray[i]; } return reverseString; } 2. Using StringBuilder: public String reverseSting(String inputString) { StringBuilder stringBuilder = new StringBuilder(inputString); stringBuilder = stringBuilder.reverse(); return stringBuilder.toString(); } OR return new StringBuilder(inputString).reverse().toString();
This is an interview question. Reverse a String in place : public class Solution4 { public static void main(String[] args) { String a = "Protijayi"; System.out.println(reverse(a)); //iyajitorP } private static String reverse(String a) { char[] ca = a.toCharArray(); int start = 0 ; int end = a.length()-1; while(end > start) { swap(ca,start,end); start++; end--; }//while return new String(ca); } private static void swap(char[] ca, int start, int end) { char t = ca[start]; ca[start] = ca[end]; ca[end] = t ; } }
Mind also, that you can avoid using additional memory during the swap, though having some extra computation. public class StringReverser { public static String reverseStringInPlace(String toReverse) { char[] chars = toReverse.toCharArray(); int inputStringLength = toReverse.length(); for (int i = 0; i < inputStringLength / 2; i++) { int toMoveBack = toReverse.charAt(i); int toMoveForward = toReverse.charAt(inputStringLength - i - 1); //swap toMoveForward = toMoveBack - toMoveForward; toMoveBack -= toMoveForward; toMoveForward += toMoveBack; chars[i] = (char) toMoveBack; chars[inputStringLength - i - 1] = (char) toMoveForward; } return String.valueOf(chars); } public static void main(String[] args) { System.out.println(reverseStringInPlace("asd0")); // output: 0dsa System.out.println(reverseStringInPlace("sd0")); // output: 0ds System.out.println(reverseStringInPlace("")); // output: empty System.out.println(reverseStringInPlace("-")); // output: - System.out.println(reverseStringInPlace("ABD+C")); // output: C+DBA System.out.println(reverseStringInPlace("勒")); // output: 勒 System.out.println(reverseStringInPlace("分歧。")); // output: 。歧分 System.out.println(reverseStringInPlace("Marítimo")); // output: omitíraM } } Relevant to swap discussion can be found here: How to swap two numbers without using temp variables or arithmetic operations?
Convert the string to a character array first and then use recursion. public void reverseString(char[] s) { helper(0, s.length - 1, s); } private void helper(int left, int right, char[] s){ if(left >= right) { return; } char temp = s[left]; s[left++] = s[right]; s[right--] = temp; helper(left, right, s); } So with the input [1,2,3,4], the helper function will be called as follows : 1. helper(0, 3, [1,2,3,4]), Swap 1 and 4 2. helper(1, 2, [1,2,3,4]), Swap 2 and 3 3. helper(2, 1, [1,2,3,4]) Terminates, left is now greater than right
After converting into char array. Just swap the both ends ( first index, last index) and move towards each other(first index to last index and from last index to first) until the crossing. public void reverseString(char[] s) { int start = 0; int end = s.length-1; char temp = ' '; while((start)<(end)){ temp = s[start]; s[start] = s[end]; s[end] = temp; start++; end--; } System.out.println(s); }
Find the first non repeating character in a string
I m writing a method to find the first non repeating character in a string. I saw this method in a previous stackoverflow question public static char findFirstNonRepChar(String input){ char currentChar = '\0'; int len = input.length(); for(int i=0;i<len;i++){ currentChar = input.charAt(i); if((i!=0) && (currentChar!=input.charAt(i-1)) && (i==input.lastIndexOf(currentChar))){ return currentChar; } } return currentChar; } I came up with a solution using a hashtable where I have two for loops (not nested) where I interate through the string in one loop writing down each occurance of a letter (for example in apple, a would have 1, p would have 2, etc.) then in the second loop I interate through the hashtable to see which one has a count of 1 first. What is the benefit to the above method over what I came up with? I am new to Java does having two loops (not nested) hinder time complexity. Both these algorithms should have O(n) right? Is there another faster, less space complexity algorithm for this question than these two solutions?
public class FirstNonRepeatCharFromString { public static void main(String[] args) { String s = "java"; for(Character ch:s.toCharArray()) { if(s.indexOf(ch) == s.lastIndexOf(ch)) { System.out.println("First non repeat character = " + ch); break; } } } }
As you asked if your code is from O(n) or not, I think it's not, because in the for loop, you are calling lastIndexOf and it's worst case is O(n). So it is from O(n^2). About your second question: having two loops which are not nested, also makes it from O(n). If assuming non unicode characters in your input String, and Uppercase or Lowercase characters are assumed to be different, the following would do it with o(n) and supports all ASCII codes from 0 to 255: public static Character getFirstNotRepeatedChar(String input) { byte[] flags = new byte[256]; //all is initialized by 0 for (int i = 0; i < input.length(); i++) { // O(n) flags[(int)input.charAt(i)]++ ; } for (int i = 0; i < input.length(); i++) { // O(n) if(flags[(int)input.charAt(i)] > 0) return input.charAt(i); } return null; } Thanks to Konstantinos Chalkias hint about the overflow, if your input string has more than 127 occurrence of a certain character, you can change the type of flags array from byte[] to int[] or long[] to prevent the overflow of byte type. Hope it would be helpful.
The algorithm you showed is slow: it looks for each character in the string, it basically means that for each character you spend your time checking the string twice!! Huge time loss. The best naive O(n) solution basically holds all the characters in order of insertion (so the first can be found) and maps a mutable integer to them. When we're done, analyzing, we go through all the entries and return the first character that was registered and has a count of 1. There are no restrictions on the characters you can use. And AtomicInteger is available with import java.util.concurrent.atomic.AtomicInteger. Using Java 8: public static char findFirstNonRepChar(String string) { Map<Integer,Long> characters = string.chars().boxed() .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())); return (char)(int)characters.entrySet().stream() .filter(e -> e.getValue() == 1L) .findFirst() .map(Map.Entry::getKey) .orElseThrow(() -> new RuntimeException("No unrepeated character")); } Non Java 8 equivalent: public static char findFirstNonRepChar(String string) { Map<Character, AtomicInteger> characters = new LinkedHashMap<>(); // preserves order of insertion. for (int i = 0; i < string.length(); i++) { char c = string.charAt(i); AtomicInteger n = characters.get(c); if (n == null) { n = new AtomicInteger(0); characters.put(c, n); } n.incrementAndGet(); } for (Map.Entry<Character, AtomicInteger> entry: characters.entries()) { if (entry.getValue().get() == 1) { return entry.getKey(); } } throw new RuntimeException("No unrepeated character"); }
import java.util.LinkedHashMap; import java.util.Map; public class getFirstNonRep { public static char get(String s) throws Exception { if (s.length() == 0) { System.out.println("Fail"); System.exit(0); } else { Map<Character, Integer> m = new LinkedHashMap<Character, Integer>(); for (int i = 0; i < s.length(); i++) { if (m.containsKey(s.charAt(i))) { m.put(s.charAt(i), m.get(s.charAt(i)) + 1); } else { m.put(s.charAt(i), 1); } } for (Map.Entry<Character, Integer> hm : m.entrySet()) { if (hm.getValue() == 1) { return hm.getKey(); } } } return 0; } public static void main(String[] args) throws Exception { System.out.print(get("Youssef Zaky")); } } This solution takes less space and less time, since we iterate the string only one time.
Works for any type of characters. String charHolder; // Holds String testString = "8uiuiti080t8xt8t"; char testChar = ' '; int count = 0; for (int i=0; i <= testString.length()-1; i++) { testChar = testString.charAt(i); for (int j=0; j < testString.length()-1; j++) { if (testChar == testString.charAt(j)) { count++; } } if (count == 1) { break; }; count = 0; } System.out.println("The first not repeating character is " + testChar);
I accumulated all possible methods with string length 25'500 symbols: private static String getFirstUniqueChar(String line) { String result1 = null, result2 = null, result3 = null, result4 = null, result5 = null; int length = line.length(); long start = System.currentTimeMillis(); Map<Character, Integer> chars = new LinkedHashMap<Character, Integer>(); char[] charArray1 = line.toCharArray(); for (int i = 0; i < length; i++) { char currentChar = charArray1[i]; chars.put(currentChar, chars.containsKey(currentChar) ? chars.get(currentChar) + 1 : 1); } for (Map.Entry<Character, Integer> entry : chars.entrySet()) { if (entry.getValue() == 1) { result1 = entry.getKey().toString(); break; } } long end = System.currentTimeMillis(); System.out.println("1st test:\n result: " + result1 + "\n time: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < length; i++) { String current = Character.toString(line.charAt(i)); String left = line.substring(0, i); if (!left.contains(current)) { String right = line.substring(i + 1); if (!right.contains(current)) { result2 = current; break; } } } end = System.currentTimeMillis(); System.out.println("2nd test:\n result: " + result2 + "\n time: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < length; i++) { char currentChar = line.charAt(i); if (line.indexOf(currentChar) == line.lastIndexOf(currentChar)) { result3 = Character.toString(currentChar); break; } } end = System.currentTimeMillis(); System.out.println("3rd test:\n result: " + result3 + "\n time: " + (end - start)); start = System.currentTimeMillis(); char[] charArray4 = line.toCharArray(); for (int i = 0; i < length; i++) { char currentChar = charArray4[i]; int count = 0; for (int j = 0; j < length; j++) { if (currentChar == charArray4[j] && i != j) { count++; break; } } if (count == 0) { result4 = Character.toString(currentChar); break; } } end = System.currentTimeMillis(); System.out.println("4th test:\n result: " + result4 + "\n time: " + (end - start)); start = System.currentTimeMillis(); for (int i = 0; i < length; i++) { char currentChar = line.charAt(i); int count = 0; for (int j = 0; j < length; j++) { if (currentChar == line.charAt(j) && i != j) { count++; break; } } if (count == 0) { result5 = Character.toString(currentChar); break; } } end = System.currentTimeMillis(); System.out.println("5th test:\n result: " + result5 + "\n time: " + (end - start)); return result1; } And time results (5 times): 1st test: result: g time: 13, 12, 12, 12, 14 2nd test: result: g time: 55, 56, 59, 70, 59 3rd test: result: g time: 2, 3, 2, 2, 3 4th test: result: g time: 3, 3, 2, 3, 3 5th test: result: g time: 6, 5, 5, 5, 6
public static char NonReapitingCharacter(String str) { Set<Character> s = new HashSet(); char ch = '\u0000'; for (char c : str.toCharArray()) { if (s.add(c)) { if (c == ch) { break; } else { ch = c; } } } return ch; }
Okay I misread the question initially so here's a new solution. I believe is this O(n). The contains(Object) of HashSet is O(1), so we can take advantage of that and avoid a second loop. Essentially if we've never seen a specific char before, we add it to the validChars as a potential candidate to be returned. The second we see it again however, we add it to the trash can of invalidChars. This prevents that char from being added again. At the end of the loop (you have to loop at least once no matter what you do), you'll have a validChars hashset with n amount of elements. If none are there, then it will return null from the Character class. This has a distinct advantage as the char class has no good way to return a 'bad' result so to speak. public static Character findNonRepeatingChar(String x) { HashSet<Character> validChars = new HashSet<>(); HashSet<Character> invalidChars = new HashSet<>(); char[] array = x.toCharArray(); for (char c : array) { if (validChars.contains(c)) { validChars.remove(c); invalidChars.add(c); } else if (!validChars.contains(c) && !invalidChars.contains(c)) { validChars.add(c); } } return (!validChars.isEmpty() ? validChars.iterator().next() : null); }
If you are only interested for characters in the range a-z (lowercase as OP requested in comments), you can use this method that requires a minimum extra storage of two bits per character Vs a HashMap approach. /* * It works for lowercase a-z * you can scale it to add more characters * eg use 128 Vs 26 for ASCII or 256 for extended ASCII */ public static char getFirstNotRepeatedChar(String input) { boolean[] charsExist = new boolean[26]; boolean[] charsNonUnique = new boolean[26]; for (int i = 0; i < input.length(); i++) { int index = 'z' - input.charAt(i); if (!charsExist[index]) { charsExist[index] = true; } else { charsNonUnique[index] = true; } } for (int i = 0; i < input.length(); i++) { if (!charsNonUnique['z' - input.charAt(i)]) return input.charAt(i); } return '?'; //example return of no character found }
In case of two loops (not nested) the time complexity would be O(n). The second solution mentioned in the question can be implemented as: We can use string characters as keys to a map and maintain their count. Following is the algorithm. 1.Scan the string from left to right and construct the count map. 2.Again, scan the string from left to right and check for count of each character from the map, if you find an element who’s count is 1, return it. package com.java.teasers.samples; import java.util.Map; import java.util.HashMap; public class NonRepeatCharacter { public static void main(String[] args) { String yourString = "Hi this is javateasers";//change it with your string Map<Character, Integer> characterMap = new HashMap<Character, Integer>(); //Step 1 of the Algorithm for (int i = 0; i < yourString.length(); i++) { Character character = yourString.charAt(i); //check if character is already present if(null != characterMap.get(character)){ //in case it is already there increment the count by 1. characterMap.put(character, characterMap.get(character) + 1); } //in case it is for the first time. Put 1 to the count else characterMap.put(character, 1); } //Step 2 of the Algorithm for (int i = 0; i < yourString.length(); i++) { Character character = yourString.charAt(i); int count = characterMap.get(character); if(count == 1){ System.out.println("character is:" + character); break; } } } }
public char firstNonRepeatedChar(String input) { char out = 0; int length = input.length(); for (int i = 0; i < length; i++) { String sub1 = input.substring(0, i); String sub2 = input.substring(i + 1); if (!(sub1.contains(input.charAt(i) + "") || sub2.contains(input .charAt(i) + ""))) { out = input.charAt(i); break; } } return out; }
Since LinkedHashMap keeps the order of insertion package com.company; import java.util.LinkedHashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] argh) { Scanner sc = new Scanner(System.in); String l = sc.nextLine(); System.out.println(firstCharNoRepeated(l)); } private static String firstCharNoRepeated(String l) { Map<String, Integer> chars = new LinkedHashMap(); for(int i=0; i < l.length(); i++) { String c = String.valueOf(l.charAt(i)); if(!chars.containsKey(c)){ chars.put(c, i); } else { chars.remove(c); } } return chars.keySet().iterator().next(); } }
Few lines of code, works for me. public class FirstNonRepeatingCharacter { final static String string = "cascade"; public static void main(String[] args) { char[] charArr = string.toCharArray(); for (int i = 0; charArr.length > i; i++) { int count = 0; for (int j = 0; charArr.length > j; j++) { if (charArr[i] == charArr[j]) { count++; } } if (count == 1){ System.out.println("First Non Repeating Character is: " + charArr[i]); break; } } } }
Constraint for this solution: O(n) time complexity. My solution is O(2n), follow Time Complexity analysis,O(2n) => O(n) import java.util.HashMap; public class FindFirstNonDuplicateCharacter { public static void main(String args[]) { System.out.println(findFirstNonDuplicateCharacter("abacbcefd")); } private static char findFirstNonDuplicateCharacter(String s) { HashMap<Character, Integer> chDupCount = new HashMap<Character, Integer>(); char[] charArr = s.toCharArray(); for (char ch: charArr) { //first loop, make the tables and counted duplication by key O(n) if (!chDupCount.containsKey(ch)) { chDupCount.put(ch,1); continue; } int dupCount = chDupCount.get(ch)+1; chDupCount.replace(ch, dupCount); } char res = '-'; for(char ch: charArr) { //second loop, get the first duplicate by count number, O(2n) // System.out.println("key: " + ch+", value: " + chDupCount.get(ch)); if (chDupCount.get(ch) == 1) { res = ch; break; } } return res; } } Hope it help
char firstNotRepeatingCharacter(String s) { for(int i=0; i< s.length(); i++){ if(i == s.lastIndexOf(s.charAt(i)) && i == s.indexOf(s.charAt(i))){ return s.charAt(i); } } return '_'; }
String a = "sampapl"; char ar[] = a.toCharArray(); int dya[] = new int[256]; for (int i = 0; i < dya.length; i++) { dya[i] = -1; } for (int i = 0; i < ar.length; i++) { if (dya[ar[i]] != -1) { System.out.println(ar[i]); break; } else { dya[ar[i]] = ar[i]; } }
This is solution in python: input_str = "interesting" #input_str = "aabbcc" #input_str = "aaaapaabbcccq" def firstNonRepeating(param): counts = {} for i in range(0, len(param)): # Store count and index repectively if param[i] in counts: counts[param[i]][0] += 1 else: counts[param[i]] = [1, i] result_index = len(param) - 1 for x in counts: if counts[x][0] == 1 and result_index > counts[x][1]: result_index = counts[x][1] return result_index result_index = firstNonRepeating(input_str) if result_index == len(input_str)-1: print("no such character found") else: print("first non repeating charater found: " + input_str[result_index]) Output: first non repeating charater found: r
import java.util.*; public class Main { public static void main(String[] args) { String str1 = "gibblegabbler"; System.out.println("The given string is: " + str1); for (int i = 0; i < str1.length(); i++) { boolean unique = true; for (int j = 0; j < str1.length(); j++) { if (i != j && str1.charAt(i) == str1.charAt(j)) { unique = false; break; } } if (unique) { System.out.println("The first non repeated character in String is: " + str1.charAt(i)); break; } } } }
public class GFG { public static void main(String[] args) { String s = "mmjjjjmmn"; for (char c : s.toCharArray()) { if (s.indexOf(c) == s.lastIndexOf(c)) { System.out.println("First non repeated is:" + c); break; } } } output = n
Non Repeated Character String in Java public class NonRepeatedCharacter { public static void main(String[] args) { String s = "ffeeddbbaaclck"; for (int i = 0; i < s.length(); i++) { boolean unique = true; for (int j = 0; j < s.length(); j++) { if (i != j && s.charAt(i) == s.charAt(j)) { unique = false; break; } } if (unique) { System.out.println("First non repeated characted in String \"" + s + "\" is:" + s.charAt(i)); break; } } } } Output: First non repeated characted in String "ffeeddbbaaclck" is:l For More Details
In this coding i use length of string to find the first non repeating letter. package com.string.assingment3; import java.util.Scanner; public class FirstNonRepetedChar { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Enter a String : "); String str = in.next(); char[] ch = str.toCharArray(); int length = ch.length; int x = length; for(int i=0;i<length;i++) { x = length-i; for(int j=i+1;j<length;j++) { if(ch[i]!=ch[j]) { x--; }//if }//inner for if(x==1) { System.out.println(ch[i]); break; } else { continue; } }//outer for } }// develope by NDM
In Kotlin fun firstNonRepeating(string: String): Char?{ //Get a copy of the string var copy = string //Slice string into chars then convert them to string string.map { it.toString() }.forEach { //Replace first occurrance of that character and check if it still has it if (copy.replaceFirst(it,"").contains(it)) //If it has the given character remove it copy = copy.replace(it,"") } //Return null if there is no non-repeating character if (copy.isEmpty()) return null //Get the first character from what left of that string return copy.first() } https://pl.kotl.in/KzL-veYNZ
public static void firstNonRepeatFirstChar(String str) { System.out.println("The given string is: " + str); for (int i = 0; i < str.length(); i++) { boolean unique = true; for (int j = 0; j < str.length(); j++) { if (i != j && str.charAt(i) == str.charAt(j)) { unique = false; break; } } if (unique) { System.out.println("The first non repeated character in String is: " + str.charAt(i)); break; } } }
Using Set with single for loop public static Character firstNonRepeatedCharacter(String str) { Character result = null; if (str != null) { Set<Character> set = new HashSet<>(); for (char c : str.toCharArray()) { if (set.add(c) && result == null) { result = c; } else if (result != null && c == result) { result = null; } } } return result; }
You can achieve this in single traversal of String using LinkedHashSet as follows: public static Character getFirstNonRepeatingCharacter(String str) { Set<Character> result = new LinkedHashSet<>(256); for (int i = 0; i< str.length(); ++i) { if(!result.add(str.charAt(i))) { result.remove(str.charAt(i)); } } if(result.iterator().hasNext()) { return result.iterator().next(); } return null; }
For Java; char firstNotRepeatingCharacter(String s) { HashSet<String> hs = new HashSet<>(); StringBuilder sb =new StringBuilder(s); for (int i = 0; i<s.length(); i++){ char c = sb.charAt(i); if(s.indexOf(c) == i && s.indexOf(c, i+1) == -1 ) { return c; } } return '_'; }
public class FirstNonRepeatingChar { public static void main(String[] args) { String s = "hello world i am here"; s.chars().boxed() .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())) .entrySet().stream().filter(e -> e.getValue() == 1).findFirst().ifPresent(e->System.out.println(e.getKey())); } }
package looping.concepts; import java.util.Scanner; public class Line { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Enter name: "); String a = sc.nextLine(); int i = 0; int j = 0; for (i = 0; i < a.length(); i++) { char ch = a.charAt(i); int counter = 0; // boolean repeat = false; for (j = 0; j < a.length(); j++) { if (ch == a.charAt(j)) { counter++; } } if (counter == 1) { System.out.print(ch); } else { System.out.print("There is no non repeated character"); break; } } } }
import java.util.Scanner; public class NonRepaeated1 { public static void main(String args[]) { String str; char non_repeat=0; int len,i,j,count=0; Scanner s = new Scanner(System.in); str = s.nextLine(); len = str.length(); for(i=0;i<len;i++) { non_repeat=str.charAt(i); count=1; for(j=0;j<len;j++) { if(i!=j) { if(str.charAt(i) == str.charAt(j)) { count=0; break; } } } if(count==1) break; } if(count == 1) System.out.print("The non repeated character is : " + non_repeat); } }
package com.test.util; public class StringNoRepeat { public static void main(String args[]) { String st = "234123nljnsdfsdf41l"; String strOrig=st; int i=0; int j=0; String st1=""; Character ch=' '; boolean fnd=false; for (i=0;i<strOrig.length(); i++) { ch=strOrig.charAt(i); st1 = ch.toString(); if (i==0) st = strOrig.substring(1,strOrig.length()); else if (i == strOrig.length()-1) st=strOrig.substring(0, strOrig.length()-1); else st=strOrig.substring(0, i)+strOrig.substring(i+1,strOrig.length()); if (st.indexOf(st1) == -1) { fnd=true; j=i; break; } } if (!fnd) System.out.println("The first no non repeated character"); else System.out.println("The first non repeated character is " +strOrig.charAt(j)); } }
permutations of a string using iteration
I'm trying to find permutation of a given string, but I want to use iteration. The recursive solution I found online and I do understand it, but converting it to an iterative solution is really not working out. Below I have attached my code. I would really appreciate the help: public static void combString(String s) { char[] a = new char[s.length()]; //String temp = ""; for(int i = 0; i < s.length(); i++) { a[i] = s.charAt(i); } for(int i = 0; i < s.length(); i++) { String temp = "" + a[i]; for(int j = 0; j < s.length();j++) { //int k = j; if(i != j) { System.out.println(j); temp += s.substring(0,j) + s.substring(j+1,s.length()); } } System.out.println(temp); } }
Following up on my related question comment, here's a Java implementation that does what you want using the Counting QuickPerm Algorithm: public static void combString(String s) { // Print initial string, as only the alterations will be printed later System.out.println(s); char[] a = s.toCharArray(); int n = a.length; int[] p = new int[n]; // Weight index control array initially all zeros. Of course, same size of the char array. int i = 1; //Upper bound index. i.e: if string is "abc" then index i could be at "c" while (i < n) { if (p[i] < i) { //if the weight index is bigger or the same it means that we have already switched between these i,j (one iteration before). int j = ((i % 2) == 0) ? 0 : p[i];//Lower bound index. i.e: if string is "abc" then j index will always be 0. swap(a, i, j); // Print current System.out.println(join(a)); p[i]++; //Adding 1 to the specific weight that relates to the char array. i = 1; //if i was 2 (for example), after the swap we now need to swap for i=1 } else { p[i] = 0;//Weight index will be zero because one iteration before, it was 1 (for example) to indicate that char array a[i] swapped. i++;//i index will have the option to go forward in the char array for "longer swaps" } } } private static String join(char[] a) { StringBuilder builder = new StringBuilder(); builder.append(a); return builder.toString(); } private static void swap(char[] a, int i, int j) { char temp = a[i]; a[i] = a[j]; a[j] = temp; }
List<String> results = new ArrayList<String>(); String test_str = "abcd"; char[] chars = test_str.toCharArray(); results.add(new String("" + chars[0])); for(int j=1; j<chars.length; j++) { char c = chars[j]; int cur_size = results.size(); //create new permutations combing char 'c' with each of the existing permutations for(int i=cur_size-1; i>=0; i--) { String str = results.remove(i); for(int l=0; l<=str.length(); l++) { results.add(str.substring(0,l) + c + str.substring(l)); } } } System.out.println("Number of Permutations: " + results.size()); System.out.println(results); Example: if we have 3 character string e.g. "abc", we can form permuations as below. 1) construct a string with first character e.g. 'a' and store that in results. char[] chars = test_str.toCharArray(); results.add(new String("" + chars[0])); 2) Now take next character in string (i.e. 'b') and insert that in all possible positions of previously contsructed strings in results. Since we have only one string in results ("a") at this point, doing so gives us 2 new strings 'ba', 'ab'. Insert these newly constructed strings in results and remove "a". for(int i=cur_size-1; i>=0; i--) { String str = results.remove(i); for(int l=0; l<=str.length(); l++) { results.add(str.substring(0,l) + c + str.substring(l)); } } 3) Repeat 2) for every character in the given string. for(int j=1; j<chars.length; j++) { char c = chars[j]; .... .... } This gives us "cba", "bca", "bac" from "ba" and "cab", "acb" and "abc" from "ab"
Work queue allows us to create an elegant iterative solution for this problem. static List<String> permutations(String string) { List<String> permutations = new LinkedList<>(); Deque<WorkUnit> workQueue = new LinkedList<>(); // We need to permutate the whole string and haven't done anything yet. workQueue.add(new WorkUnit(string, "")); while (!workQueue.isEmpty()) { // Do we still have any work? WorkUnit work = workQueue.poll(); // Permutate each character. for (int i = 0; i < work.todo.length(); i++) { String permutation = work.done + work.todo.charAt(i); // Did we already build a complete permutation? if (permutation.length() == string.length()) { permutations.add(permutation); } else { // Otherwise what characters are left? String stillTodo = work.todo.substring(0, i) + work.todo.substring(i + 1); workQueue.add(new WorkUnit(stillTodo, permutation)); } } } return permutations; } A helper class to hold partial results is very simple. /** * Immutable unit of work */ class WorkUnit { final String todo; final String done; WorkUnit(String todo, String done) { this.todo = todo; this.done = done; } } You can test the above piece of code by wrapping them in this class. import java.util.*; public class AllPermutations { public static void main(String... args) { String str = args[0]; System.out.println(permutations(str)); } static List<String> permutations(String string) { ... } } class WorkUnit { ... } Try it by compiling and running. $ javac AllPermutations.java; java AllPermutations abcd The below implementation can also be easily tweaked to return a list of permutations in reverse order by using a LIFO stack of work instead of a FIFO queue.
import java.util.List; import java.util.Set; import java.util.ArrayList; import java.util.HashSet; public class Anagrams{ public static void main(String[] args) { String inpString = "abcd"; Set<String> combs = getAllCombs(inpString); for(String comb : combs) { System.out.println(comb); } } private static Set<String> getAllCombs(String inpString) { Set<String> combs = new HashSet<String>(); if( inpString == null | inpString.isEmpty()) return combs; combs.add(inpString.substring(0,1)); Set<String> tempCombs = new HashSet<String>(); for(char a : inpString.substring(1).toCharArray()) { tempCombs.clear(); tempCombs.addAll(combs); combs.clear(); for(String comb : tempCombs) { combs.addAll(getCombs(comb,a)); } } return combs; } private static Set<String> getCombs(String comb, char a) { Set<String> combs = new HashSet<String>(); for(int i = 0 ; i <= comb.length(); i++) { String temp = comb.substring(0, i) + a + comb.substring(i); combs.add(temp); //System.out.println(temp); } return combs; } }
Just posting my approach to the problem: import java.util.ArrayDeque; import java.util.Queue; public class PermutationIterative { public static void main(String[] args) { permutationIterative("abcd"); } private static void permutationIterative(String str) { Queue<String> currentQueue = null; int charNumber = 1; for (char c : str.toCharArray()) { if (currentQueue == null) { currentQueue = new ArrayDeque<>(1); currentQueue.add(String.valueOf(c)); } else { int currentQueueSize = currentQueue.size(); int numElements = currentQueueSize * charNumber; Queue<String> nextQueue = new ArrayDeque<>(numElements); for (int i = 0; i < currentQueueSize; i++) { String tempString = currentQueue.remove(); for (int j = 0; j < charNumber; j++) { int n = tempString.length(); nextQueue.add(tempString.substring(0, j) + c + tempString.substring(j, n)); } } currentQueue = nextQueue; } charNumber++; } System.out.println(currentQueue); } }
package vishal villa; import java.util.Scanner; public class Permutation { static void result( String st, String ans) { if(st.length() == 0) System.out.println(ans +" "); for(int i = 0; i<st.length(); i++) { char ch = st.charAt(i); String r = st.substring(0, i) + st.substring(i + 1); result(r, ans + ch); } } public static void main(String[] args) { Scanner Sc = new Scanner(System.in); System.out.println("enter the string"); String st = Sc.nextLine(); Permutation p = new Permutation(); p.result(st,"" ); } }
// Java program to print all permutations of a // given string. public class Permutation { public static void main(String[] args) { String str = "ABC"; int n = str.length(); Permutation permutation = new Permutation(); permutation.permute(str, 0, n-1); } /** * permutation function * #param str string to calculate permutation for * #param s starting index * #param e end index */ private void permute(String str, int s, int e) { if (s == e) System.out.println(str); else { for (int i = s; i <= s; i++) { str = swap(str,l,i); permute(str, s+1, e); str = swap(str,l,i); } } } /** * Swap Characters at position * #param a string value * #param i position 1 * #param j position 2 * #return swapped string */ public String swap(String a, int i, int j) { char temp; char[] charArray = a.toCharArray(); temp = charArray[i] ; charArray[i] = charArray[j]; charArray[j] = temp; return String.valueOf(charArray); } }