Finding most frequency number in array - java

By using following I am able to find most frequently occurring integer in an array. But following code it will not work for few scenarios. How can I fix the code inside for loop? I want to enhance this approach only.
class FindingMostFrequencyOccur {
public static void main(String args[]) {
int A[] = { 1, 2, 3, 3, 1, 3, 1};
int M = 3; // Maximum Number in Array
int result = findFrequency(M, A);
System.out.println("Result "+result);
}
static int findFrequency(int M, int[] A) {
int N = A.length;
int[] count = new int[M + 1];
for (int i = 0; i <= M; i++)
count[i] = 0;
int maxOccurence = 1;
int index = -1;
for (int i = 0; i < N; i++) {
if (count[A[i]] > 0) {
int tmp = count[A[i]];
if (tmp > maxOccurence) {
maxOccurence = tmp;
index = i;
}
count[A[i]] = tmp + 1;
} else {
count[A[i]] = 1;
}
}
return A[index];
}
}
Can you we improve in this line
if (count[A[i]] > 0) {
int tmp = count[A[i]];
if (tmp > maxOccurence) {
maxOccurence = tmp;
index = i;
}
count[A[i]] = tmp + 1;
} else {
count[A[i]] = 1;
}

To get the frequency of m in a use:
static int findFrequency(int m, int[] a) {
return (int)IntStream.of(a).filter(i-> i==m).count();
}
To get a map of all frequencies in a use:
static Map<Integer, Integer> findFrequency(int[] a) {
Map<Integer, Integer> m = new HashMap<>();
IntStream.of(a).distinct().forEach(i->{
m.put(i, findFrequency(i,a));
});
return m;
}

In this logic, you take each element of the array, and find the number of times it is repeated to the right of it, in the array. This is given by local_frequency. If this happens to be more than max_frequency, then this number at arr[i] is stored in number, and then max_frequency stores local_frequency
public static void main(String[] args)
{
int[] arr = {1, 2, 3, 4, 3, 2, 1, 5, 5, 5, 4, 4, 3, 4};
int result = findMostFrequent(arr);
System.out.println(result + " is the most frequent number");
}
public static int findMostFrequent(int[] arr)
{
int number = arr[0];
int maxFrequency = 0;
for(int i =0 ; i < arr.length; i++)
{
int local_frequency = 0;
for(int j = i; j < arr.length; j++)
{
if(arr[i] == arr[j])
local_frequency++;
}
if(local_frequency > maxFrequency)
{
number = arr[i];
maxFrequency = local_frequency;
}
}
return number;
}

Related

Reconstructing the path that gives the maximum path sum in a matrix

I'm trying to find a maximum path sum in the matrix. The starting position must be in a[0][0] (top-left) and the ending position must be in a[n][m] (bottom-right). The move is only allowed to the right, down, or diagonal.
Here is my solution:
public class Main {
public static int maxa(int[][] a) {
int m = a.length, n = a[0].length;
int[][] dp = new int[m][n];
dp[0][0] = a[0][0];
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0] + a[i][0];
}
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1] + a[0][j];
}
System.out.println("Route Path: ");
System.out.print(a[0][0] + " ");
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = findMax(dp[i - 1][j], dp[i][j - 1], dp[i-1][j-1]) + a[i][j];
if (a[i - 1][j] > a[i][j - 1]) {
System.out.print(a[i - 1][j] + " ");
} else {
System.out.print(a[i][j - 1] + " ");
}
}
}
System.out.print(a[m - 1][n - 1] + " ");
System.out.println();
System.out.println("Result: ");
return dp[m - 1][n - 1];
}
public static int findMax(int num1, int num2, int num3) {
if (num1 >= num2 && num1 >= num3)
return num1;
else if (num2 >= num1 && num2 >= num3)
return num2;
else
return num3;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int MAX = 30;
int MIN = -30;
Random random = new Random();
System.out.print("Enter values of Rows: ");
int n = input.nextInt();
System.out.print("Enter values of Columns: ");
int m = input.nextInt();
int[][] myMatrix = new int[n][m];
for (int row = 0; row < n; row++) {
for (int col = 0; col < m; col++) {
// myMatrix[row][col] = random.nextInt(MAX - MIN) + MIN;
myMatrix[row][col] = input.nextInt();
}
}
System.out.println();
System.out.println("Your Random Matrix: ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
System.out.print(myMatrix[i][j] + "\t");
}
System.out.println();
}
System.out.println();
System.out.println(maxa(myMatrix));
}
}
The result of the sum is correct but my code gives the wrong route path.
For example, if I have a 3x3 matrix = [{1,2,3},{4,-5,6},{7-8,9}], then the result sum I get is 22 which is correct, but the route path I get is 1 4 3 -5 8 9 which is wrong. I expected my route path output to be 1 4 8 9.
What can I do to fix the problem and produce the correct path?
I'm not sure I follow your expected output, but the inline prints are generally not a great approach to the problem. Generally, you want to compute it without a side effect and return it so the caller can use the result programmatically, optionally to print.
In any case, your printing condition if (a[i - 1][j] > a[i][j - 1]) isn't enough to differentiate which of 3 possible moves was chosen on the best path. We need to find the largest of 3 subproblems in the DP table, not the input matrix -- looking at a is meaningless because it's only a local maxima at best.
In the case of a tie, it doesn't matter which move we pick from the DP table, all tied subproblems have equally maximal path scores.
While it's possible to figure out which number was taken along the way up by making that 3-way comparison, the typical(?) approach I'm familiar with for DP is to backtrack from dp[m-1][n-1] to dp[0][0] and reconstruct the path based on the DP table. It's free lunch from a time complexity standpoint and lets you separate the logic into a distinct function.
The logic for rebuilding the path is:
Start at i = m - 1, j = n - 1 (the bottom-right corner).
Repeat until i == 0 and j == 0 (the top-left corner):
Add a[i][j] to the path.
If i > 0 and j > 0, find the best of dp[i-1][j], dp[i-1][j-1], dp[i][j-1]. If the best was [i-1][j-1], decrement both i and j by 1 -- we took a diagonal move; otherwise decrement either i or j depending on which move was better.
Otherwise, i == 0 or j == 0 and the path is on a top or left edge and we'll just decrement i or j until we get to the goal.
Add a[0][0] to the path, reverse it and return it.
Here's a proof of concept:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Main {
public static int maxPathSum(int[][] a) {
final var table = makeDPTable(a);
if (table.length > 0 && table[0].length > 0) {
return table[table.length-1][table[0].length-1];
}
return 0;
}
public static ArrayList<Integer> maxPath(int[][] a) {
return reconstructPath(makeDPTable(a), a);
}
private static ArrayList<Integer> reconstructPath(int dp[][], int a[][]) {
final int m = a.length;
if (m == 0) {
return new ArrayList<Integer>();
}
final int n = a[0].length;
final var path = new ArrayList<Integer>();
for (int i = m - 1, j = n - 1; i > 0 || j > 0;) {
path.add(a[i][j]);
if (i > 0 && j > 0) {
final int bestIdx = indexOfMax(
dp[i-1][j-1],
dp[i][j-1],
dp[i-1][j]
);
switch (bestIdx) {
case 0: i--;
case 1: j--; break;
case 2: i--; break;
}
}
else if (i > 0) {
i--;
}
else {
j--;
}
}
path.add(a[0][0]);
Collections.reverse(path);
return path;
}
private static int[][] makeDPTable(int[][] a) {
final int m = a.length;
if (m == 0) {
return new int[0][0];
}
final int n = a[0].length;
final var dp = new int[m][n];
dp[0][0] = a[0][0];
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i-1][0] + a[i][0];
}
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j-1] + a[0][j];
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = a[i][j] + max(
dp[i-1][j],
dp[i][j-1],
dp[i-1][j-1]
);
}
}
return dp;
}
private static int max(int ...nums) {
if (nums.length == 0) {
throw new IllegalArgumentException("nums cannot be empty");
}
int largest = nums[0];
for (int num : nums) {
largest = Math.max(num, largest);
}
return largest;
}
private static int indexOfMax(int ...nums) {
if (nums.length == 0) {
return -1;
}
int largest = nums[0];
int idx = 0;
for (int i = 1; i < nums.length; i++) {
if (nums[i] > largest) {
largest = nums[i];
idx = i;
}
}
return idx;
}
private static void print(int[][] m) {
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[0].length; j++) {
System.out.print(StringUtils.padLeft(m[i][j], 3));
}
System.out.println();
}
}
public static void main(String[] args) {
var tests = new TestCase[] {
new TestCase(
new int[][] {
{1, 2, 3},
{4,-5, 6},
{7,-8, 9},
},
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 6, 9)),
21
),
new TestCase(
new int[][] {
{1, 2, 3},
{4,-5, 6},
{7, 8, 9},
},
new ArrayList<Integer>(Arrays.asList(1, 4, 7, 8, 9)),
29
),
new TestCase(
new int[][] {
{1, 2, 3, 20},
{4,-5, 6, -5},
{7, 8, 9, 10},
},
new ArrayList<Integer>(Arrays.asList(1, 4, 7, 8, 9, 10)),
39
),
new TestCase(
new int[][] {
{1, 2, 3, -2},
{4,-5, -1, 20},
{0, 0, 9, 10},
},
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 20, 10)),
36
),
new TestCase(
new int[][] {
{-1, -2, -3, -2},
{-4, -5, -1, -2},
},
new ArrayList<Integer>(Arrays.asList(-1, -2, -1, -2)),
-6
),
new TestCase(new int[][] {}, new ArrayList<Integer>(), 0),
};
for (var testCase : tests) {
if (maxPathSum(testCase.m) != testCase.expectedSum) {
print(testCase.m);
System.out.println("got sum: " + maxPathSum(testCase.m));
System.out.println("expected: " + testCase.expectedSum + "\n");
}
if (!maxPath(testCase.m).equals(testCase.expectedPath)) {
print(testCase.m);
System.out.println("got path: " + maxPath(testCase.m));
System.out.println("expected: " + testCase.expectedPath + "\n");
}
}
}
}
class TestCase {
public final int[][] m;
public final ArrayList<Integer> expectedPath;
public final int expectedSum;
public TestCase(
int[][] m,
ArrayList<Integer> expectedPath,
int expectedSum
) {
this.m = m;
this.expectedPath = expectedPath;
this.expectedSum = expectedSum;
}
}
class StringUtils {
public static <T> String padLeft(T t, int n) {
return String.format("%" + n + "s", t);
}
}

Finding contiguous array

I am trying to get an output of [4,6,6,7] with length 4 where arr[i] <= arr[i+1] where it is non-decreasing and it is contiguous. I know what i have to do but i dont know how to do it. my code prints out [3,4,6,6,7]. I am just having trouble on the contiguous part, any help? im not allowed to use extra arrays.
public static void ascentLength(int arr[], int size) {
int length = 0;
int index = 0;
int count = 1;
for (int i = 0; i < size-1; i++) {
index = i;
if (arr[0] <= arr[i+1] && count >0) {
System.out.println(arr[i]+ " index:" + index);
length++;
count++;
}
if (arr[0] >= arr[i+1]) {
}
}
System.out.println("length: " + length);
}
/* Driver program to test above function */
public static void main(String[] args) {
int arr[] = {5, 3, 6, 4, 6, 6, 7, 5};
int n = arr.length;
ascentLength(arr, n);
}
Here is my solution, it would be easier, if you could work with List, but this works for arrays:
public static void ascentLength(int arr[], int size) {
if(size == 1) System.out.println("length: 1");
// variables keeping longest values
int longestStartingIndex = 0;
int longestLength = 1;
// variables keeping current values
int currentStartingIndex = 0;
int currentCount = 1;
for (int i = 1; i < size; i++) {
if (arr[i-1] <= arr[i]) {
currentCount++;
} else {
// check if current count is the longest
if(currentCount > longestLength) {
longestLength = currentCount;
longestStartingIndex = currentStartingIndex;
}
currentStartingIndex = i;
currentCount = 1;
}
}
if(currentCount > longestLength) {
longestLength = currentCount;
longestStartingIndex = currentStartingIndex;
}
}

search palindrome number in a list of array. if there exist palindrome number in the list, return its size

Check if there exists a Palindrome Number in the list.
If found return its size, else return -1.
public class Program{
public static boolean palindrome(String list){
String reversedString = "";
for (int i = list.length() -1; i >=0; i--){
reveresedString += list.charAt(i)
}
return list.equals(revereseString);
}
}
sample input: [3,5,2,6,3,6,2,1]
palindrome number found: [2,6,3,6,2]
sample output: 5
Here is a pseudo code.
output = -1;
for (i = 0; i < list.length; i++){
num = list[i];
indices[] = \\ get all the indices which the "num" value appears, only include those indices that are greater than "i"
for (j = 0; j < indices.length; j++){
flag = true;
k = i;
for (l = indices[j]; l >= k; l--, k++){
if (list[k] != list[l]) {
flag = false;
break;
}
}
if (flag){
length = (indices[j] - i) + 1;
if (length != 1 && length > output) { // checking of length != 1 will exclude those palindromes of length 2
output = length;
}
}
}
}
return output;
Here is the full code.
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
int[] list = { 3, 5, 2, 2, 6, 3, 6, 3, 6, 3, 6, 2, 2, 1 };
System.out.print(palindrome(list));
}
public static int palindrome(int[] list) {
int output = -1;
for (int i = 0; i < list.length; i++) {
int num = list[i];
ArrayList<Integer> indices = getIndices(list, i, num);
for (int j = 0; j < indices.size(); j++) {
boolean flag = true;
int k = i;
for (int l = indices.get(j); l >= k; l--, k++) {
if (list[k] != list[l]) {
flag = false;
break;
}
}
if (flag) {
int length = (indices.get(j) - i) + 1;
if (length != 1 && length > output) {
output = length;
}
}
}
}
return output;
}
public static ArrayList<Integer> getIndices(int[] list, int start, int num) {
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i = start + 1; i < list.length; i++) {
if (list[i] == num) {
result.add(i);
}
}
return result;
}
}

Find the longest subarray with distinct integers

Write a method that takes an array of integers and returns the length of its longest subarray with distinct integers.
e.g. with [1,2,3,4,2,3] it should return 4.
I used a HashSet to keep track of all elements from index i to index j and kept a counter while traversing through the list. Linear runtime and space:
public static int longestSubarray(int[] arr) {
int i = 0, j = 1, max = 0, currLength = 1;
max = Math.max(max, currLength);
HashSet<Integer> set = new HashSet<Integer>();
set.add(arr[0]);
while (i < arr.length - 1 && j < arr.length) {
if (!set.contains(arr[j])) {
currLength++;
set.add(arr[j++]);
}
else {
set.remove(arr[i++]);
currLength--;
}
}
return Math.max(currLength, max);
}
public int[] getLargestSubArray(int[] array) {
int length = array.length;
Set<Integer> set = new HashSet<>();
int longest = 0;
int start = 0;
int longestCurrent = 0;
int startCurrent = 0;
int j = 0;
while (j < length) {
if (!set.contains(array[j])) {
set.add(array[j]);
longestCurrent++;
if (longestCurrent > longest) {
longest = longestCurrent;
start = startCurrent;
}
j++;
} else {
while (startCurrent < j) {
longestCurrent--;
if (array[startCurrent++] == (array[j])) {
break;
}
}
set.remove(array[j]);
}
}
int[] longestSubSequence = new int[longest];
System.arraycopy(array, start, longestSubSequence, 0, longest);
return longestSubSequence;
}
public static int sizeOfLongestDistinctSubArrayO1(int[] arr) {
int max = 0;
Map<Integer, Integer> counts = new HashMap<>();
int cur = 0;
int prev = 0;
for (int i = 0, len = arr.length; i < len; i++) {
if (counts.containsKey(arr[i])) {
int j = counts.get(arr[i]);
max = Math.max(max, cur);
prev = Math.max(j, prev);
cur = i - prev;
counts.put(arr[i], i);
} else {
cur++;
counts.put(arr[i], i);
}
}
return Math.max(max, cur);
}
python version
#!/usr/bin/env python3
input = [1,2,3,4,2,3,4,5,6,7,3,4]
tmp_list = []
max = 0
for i in input:
if i not in tmp_list:
tmp_list.append(i)
else:
max = len(tmp_list) if len(tmp_list) > max else max
tmp_list = [i]
print (max if max >= len(tmp_list) else len(tmp_list))
public int lengthOfLongestSubarray(int[] arr) {
int max = 0; // Maximum length of subarray with unique elements
Map<Integer,Integer> map = new HashMap<>();
// let longest subarray starts at i and ends at j
for(int i = -1,j = 0; j < arr.length;j++) {
if(map.containsKey(arr[j])) {
i = Math.max(i,map.get(arr[j]));
}
max = Math.max(max,j-i);
map.put(arr[j],j);
}
return max;
}
C# Version
Core Logic:
private static int Solve(string s) {
var dict = new Dictionary < string,int > ();
var arr = s.Split(" ", StringSplitOptions.RemoveEmptyEntries);
var start = 0;
var substrLen = 0;
for (var i = 0; i < arr.Length; i++) {
if (dict.ContainsKey(arr[i])) {
substrLen = substrLen < i - start ? i - start: substrLen;
var tempStart = dict[arr[i]] + 1;
for (var j = dict[arr[i]]; j > start; j--) {
dict.Remove(arr[i]);
}
start = tempStart;
dict[arr[i]] = i;
}
else {
dict.Add(arr[i], i);
}
}
return dict.Count;
}
Complete code here
import java.util.*;
class GFG{
static int largest_subarray(int a[], int n)
{
HashSet<Integer> set = new HashSet<Integer>();
int ans = 0;
int counter = 0;
for(int i = 0; i < n; i++)
{
if(set.contains(a[i])){
set.clear();
counter =0;
}
set.add(a[i]);
counter++;
ans = Math.max(ans, counter);
}
// Return final ans
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 4, 4, 5, 6, 7, 8, 3, 4, 5, 3, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4
};
int n = arr.length;
System.out.print(largest_subarray(arr, n));
}
}

Generating permutations of an int array using java -- error

I am writing a JAVA code to generate all permutations of a integer array.
Though I am getting the number of permutations right, the permutations themselves are not correct.
On running I obtain:
Input array Length
3
1
2
3
0Permutation is
1, 2, 3,
##########################
1Permutation is
1, 3, 2,
##########################
2Permutation is
3, 1, 2,
##########################
3Permutation is
3, 2, 1,
##########################
4Permutation is
1, 2, 3,
##########################
5Permutation is
1, 3, 2,
##########################
6 number of permutations obtained
BUILD SUCCESSFUL (total time: 3 seconds)
public class PermulteArray {
public static int counter = 0;
public static void Permute(int[] input, int startindex) {
int size = input.length;
if (size == startindex + 1) {
System.out.println(counter + "Permutation is");
for (int i = 0; i < size; i++) {
System.out.print(input[i] + ", ");
}
System.out.println();
System.out.println("##########################");
counter++;
} else {
for (int i = startindex; i < size; i++) {
int temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
Permute(input, startindex + 1);
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Input array Length");
int arraylength = in.nextInt();
int[] input = new int[arraylength];
for (int i = 0; i < arraylength; i++) {
input[i] = in.nextInt();
}
counter = 0;
Permute(input, 0);
System.out.println(counter + " number of permutations obtained");
}
}
int temp=input[i];
input[i]=input[startindex];
input[startindex]=temp;
Permute(input, startindex+1);
You've swapped an element before calling Permute but you need to swap it back again afterwards to keep consistent positions of elements across iterations of the for-loop.
This is the best solution I have seen so far :
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6 };
permute(0, a);
}
public static void permute(int start, int[] input) {
if (start == input.length) {
//System.out.println(input);
for (int x : input) {
System.out.print(x);
}
System.out.println("");
return;
}
for (int i = start; i < input.length; i++) {
// swapping
int temp = input[i];
input[i] = input[start];
input[start] = temp;
// swap(input[i], input[start]);
permute(start + 1, input);
// swap(input[i],input[start]);
int temp2 = input[i];
input[i] = input[start];
input[start] = temp2;
}
}
check this out
for (int i = startindex; i < input2.length; i++) {
char[] input = input2.clone();
char temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
permute(input, startindex + 1);
}
//This will give correct output
import java.util.Scanner;
public class PermulteArray {
public static int counter = 0;
public static void Permute(int[] input, int startindex) {
int size = input.length;
if (size == startindex + 1) {
System.out.println(counter + "Permutation is");
for (int i = 0; i < size; i++) {
System.out.print(input[i] + ", ");
}
System.out.println();
System.out.println("##########################");
counter++;
} else {
for (int i = startindex; i < size; i++) {
int temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
Permute(input, startindex + 1);
temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Input array Length");
int arraylength = in.nextInt();
int[] input = new int[arraylength];
for (int i = 0; i < arraylength; i++) {
input[i] = in.nextInt();
}
counter = 0;
Permute(input, 0);
System.out.println(counter + " number of permutations obtained");
}
}
You can solve this using recursive calls.
https://github.com/Pratiyush/Master/blob/master/Algorithm%20Tutorial/src/arrays/Permutations.java
public void swap(int[] arr, int i, int j)
{
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public void permute(int[] arr, int i)
{
if (i == arr.length)
{
System.out.println(Arrays.toString(arr));
return;
}
for (int j = i; j < arr.length; j++)
{
swap(arr, i, j);
permute(arr, i + 1); // recurse call
swap(arr, i, j); // backtracking
}
}
public static void main(String[] args) {
Permutations permutations = new Permutations();
int[] arr = {1, 2, 3,4};
permutations.permute(arr, 0);
}
Also, other approaches are available in
http://www.programcreek.com/2013/02/leetcode-permutations-java/
http://www.programcreek.com/2013/02/leetcode-permutations-ii-java/
public class PermuteArray {
public static void permute(char[] input2, int startindex) {
if (input2.length == startindex) {
displayArray(input2);
} else {
for (int i = startindex; i < input2.length; i++) {
char[] input = input2.clone();
char temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
permute(input, startindex + 1);
}
}
}
private static void displayArray(char[] input) {
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + "; ");
}
System.out.println();
}
public static void main(String[] args) {
char[] input = { 'a', 'b', 'c', 'd'};
permute(input, 0);
}
}
import java.util.ArrayList;
public class RecursivePermGen {
void permGen(int n, int m, ArrayList<Integer> cur) {
if(m == 0) {
System.out.println(cur);
return;
}
for(int i = 1; i <= n; i++) {
cur.add(0, i);
permGen(n, m-1, cur);
cur.remove(0);
}
}
public static void main(String[] args) {
RecursivePermGen pg = new RecursivePermGen();
ArrayList<Integer> cur = new ArrayList<Integer>();
pg.permGen(2, 2, cur);
}
}
I have simple answer for this question, you can try with this.
public class PermutationOfString {
public static void main(String[] args) {
permutation("123");
}
private static void permutation(String string) {
printPermutation(string, "");
}
private static void printPermutation(String string, String permutation) {
if (string.length() == 0) {
System.out.println(permutation);
return;
}
for (int i = 0; i < string.length(); i++) {
char toAppendToPermutation = string.charAt(i);
String remaining = string.substring(0, i) + string.substring(i + 1);
printPermutation(remaining, permutation + toAppendToPermutation);
}
}
}
A solution i have used several times (mostly for testing purposes) is in the following gist. It is based on the well-known algorithm to generate permutations in lexicographic order (no recursion):
/**
* Compute next (in lexicographic order) permutation and advance to it.
*
* Find greater index i for which a j exists, such that:
* j > i and a[i] < a[j] (i.e. the 1st non-inversion).
* For those j satisfying the above, we pick the greatest.
* The next permutation is provided by swapping
* items at i,j and reversing the range a[i+1..n]
*/
void advanceToNext() {
// The array `current` is the permutation we start from
// Find i when 1st non-inversion happens
int i = n - 2;
while (i >= 0 && current[i] >= current[i + 1])
--i;
if (i < 0) {
// No next permutation exists (current is fully reversed)
current = null;
return;
}
// Find greater j for given i for 1st non-inversion
int j = n - 1;
while (current[j] <= current[i])
--j;
// Note: The range a[i+1..n] (after swap) is reverse sorted
swap(current, i, j); // swap current[i] <-> current[j]
reverse(current, i + 1, n); // reverse range [i+1..n]
}
A complete solution (in the form of a class) lies here:
https://gist.github.com/drmalex07/345339117fef6ca47ca97add4175011f

Categories