Java function to calculate permutations without repeats - java

I have an ArrayList and I want to find all of the combinations of a given size without repeats inside it with a single function (built in or not). For example:
ArrayList<Integer> numbers = Array.asList(96, 32, 65, 21);
getCombinationsWithoutRepeats(numbers, 2);
Output:
>>> [[96, 32], [96, 65], [96, 21], [32, 65], [32, 21], [65, 21]]
How would I create this function or is there an inbuilt function that does this?

Here is a sample solution, using backtracking. It will generate you all possible permutations of size K and store them in lists field.
List<List<Integer>> lists = new ArrayList<List<Integer>>();
void permutate(int[] arr, int k) {
internalPermutate(arr, k, 0, 0);
}
void internalPermutate(int[] arr, int k, int step, int index) {
if (step == k) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < k; i++) {
list.add(arr[i]);
}
lists.add(list);
}
for (int i = step + index; i < arr.length; i++) {
swap(arr, step, i);
internalPermutate(arr, k, step + 1, i);
swap(arr, step, i);
}
}
private void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
public static void main(String[] args) {
new SomeClass().permutate(new int[] { 1, 2, 3, 4 }, 2);
System.out.println(lists);
}
This solution doesn't deal with situation when we have the same elements in array, but you can just exclude them before permutation.

Related

Counting the number of cycles in an Undirected Graph

Question
Write a JAVA program to count the number of cycles in an Undirected graph.
My approach:
I tried solving this using Depth First Search.
I found a program online that counts the cycles of length n in an undirected and connected graph.
The code is from: https://www.geeksforgeeks.org/cycles-of-length-n-in-an-undirected-and-connected-graph/
I modified that by creating a function count(). Which checks the number of cycles in the graph for different lengths using a for loop. The code I've gotten so far is attatched below.
For the following graph,
The output I get is
However, isn't the answer supposed to be 3?
Following 3 unique cycles
0 -> 1 -> 2 -> 3 -> 0
0 -> 1 -> 4 -> 3 -> 0
1 -> 2 -> 3 -> 4 -> 1
public class Main
{
public static final int V = 5;
static int count = 0;
static void DFS(int graph[][], boolean marked[],int n, int vert, int start)
{
marked[vert] = true;
if (n == 0)
{
marked[vert] = false;
if (graph[vert][start] == 1)
{
count++;
return;
}
else
return;
}
for (int i = 0; i < V; i++)
if (!marked[i] && graph[vert][i] == 1)
DFS(graph, marked, n-1, i, start);
marked[vert] = false;
}
static int countCycles(int graph[][], int n)
{
boolean marked[] = new boolean[V];
for (int i = 0; i < V - (n - 1); i++)
{
DFS(graph, marked, n-1, i, i);
marked[i] = true;
}
return count / 2;
}
public static int count(int graph[][])
{
int count=0;
for(int i=3;i<6;i++) //i starts at 3 because the minimum length of a cycle is 3.
count+=countCycles(graph,i);
return count;
}
// driver code
public static void main(String[] args)
{
int graph[][] = {{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0}};
System.out.println("Total cycles are "+count(graph));
}
}
I finally found a solution to this using DFS and Graph colouring method.
//Program to count the number of cycles in an Undirected Graph
import java.util.*;
class Graph
{
static final int N = 100000;
#SuppressWarnings("unchecked")
static Vector<Integer>[] graph = new Vector[N];
#SuppressWarnings("unchecked")
static Vector<Integer>[] cycles = new Vector[N];
static int cyclenumber;
// Function to mark the vertex with
// different colors for different cycles
static void dfs_cycle(int u, int p, int[] color,int[] mark, int[] par)
{
// already (completely) visited vertex.
if (color[u] == 2)
{
return;
}
// seen vertex, but was not completely visited -> cycle detected.
// backtrack based on parents to find the complete cycle.
if (color[u] == 1)
{
cyclenumber++;
int cur = p;
mark[cur] = cyclenumber;
// backtrack the vertex which are
// in the current cycle thats found
while (cur != u)
{
cur = par[cur];
mark[cur] = cyclenumber;
}
return;
}
par[u] = p;
// partially visited.
color[u] = 1;
// simple dfs on graph
for (int v : graph[u])
{
// if it has not been visited previously
if (v == par[u])
{
continue;
}
dfs_cycle(v, u, color, mark, par);
}
// completely visited.
color[u] = 2;
}
// add the edges to the graph
static void addEdge(int u, int v)
{
graph[u].add(v);
graph[v].add(u);
}
//Driver code
public static void main(String[] args)
{
for (int i = 0; i < N; i++)
{
graph[i] = new Vector<>();
cycles[i] = new Vector<>();
}
//Modify edges accordingly
addEdge(1, 2);
addEdge(2, 4);
addEdge(4, 3);
addEdge(1, 3);
addEdge(3, 5);
addEdge(4, 5);
addEdge(4, 6);
int[] color = new int[N];
int[] par = new int[N];
int[] mark = new int[N];
cyclenumber = 0;
dfs_cycle(1, 0, color, mark, par);
if(cyclenumber>0)
{
System.out.println("CYCLE DETECTED!");
System.out.println("Number of cycles: "+cyclenumber);
}
else
{
System.out.println("CYCLE NOT DETECTED");
}
}
}

Return all permutations of a given list recursively

The following algorithm prints all permutations of a given list arr:
public class Permute {
static void permute(java.util.List<Integer> arr, int k) {
for (int i = k; i < arr.size(); i++) {
java.util.Collections.swap(arr, i, k);
permute(arr, k + 1);
java.util.Collections.swap(arr, k, i);
}
if (k == arr.size() - 1) {
System.out.println(java.util.Arrays.toString(arr.toArray()));
}
}
public static void main(String[] args) {
Permute.permute(java.util.Arrays.asList(1, 2, 3), 0);
}
}
(FYI: The algorithm is taken from this answer)
I would like to modify the algorithm so that it returns a list of all solutions instead of printing them, i.e. something like:
static List<List<Integer>> permute(java.util.List<Integer> arr, int k);
How would I do this? I tried the following modification of the algorithm, but it didn't work:
public class Permute {
static List<List<Integer>> permute(java.util.List<Integer> arr, int k) {
List<List<Integer>> arrs = new ArrayList<>();
for (int i = k; i < arr.size(); i++) {
java.util.Collections.swap(arr, i, k);
arrs.addAll(permute(arr, k + 1));
java.util.Collections.swap(arr, k, i);
}
if (k == arr.size() - 1) {
arrs.add(arr);
System.out.println(java.util.Arrays.toString(arr.toArray()));
}
return arrs;
}
public static void main(String[] args) {
List<Integer> arr = new ArrayList<>(Arrays.asList(1, 2, 3));
System.out.println(Permute.permute(arr, 0));
}
}
The code compiles and executes, but gives the wrong result of [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]. I'm having trouble seeing why the code doesn't work and how to do it correctly. Any help is appreciated.
You need to add a copy of the List to the result instead of adding the same one each time.
Change
arrs.add(arr);
To
arrs.add(new ArrayList<>(arr));
Full method:
static List<List<Integer>> permute(java.util.List<Integer> arr, int k) {
List<List<Integer>> arrs = new ArrayList<>();
for (int i = k; i < arr.size(); i++) {
java.util.Collections.swap(arr, i, k);
arrs.addAll(permute(arr, k + 1));
java.util.Collections.swap(arr, k, i);
}
if (k == arr.size() - 1) {
arrs.add(new ArrayList<>(arr));
}
return arrs;
}
Demo
As Unmitigated has pointed out, you need to add a copy of the permuted list.
Also, there's no need to create a new list to hold permutations at each level of the recursion. You could create a single list to hold the results and pass it as an argument:
static void permute(List<List<Integer>> res, List<Integer> arr, int k) {
if (k == arr.size() - 1) {
res.add(new ArrayList<>(arr));
return;
}
for (int i = k; i < arr.size(); i++) {
Collections.swap(arr, i, k);
permute(res, arr, k + 1);
Collections.swap(arr, k, i);
}
}
public static void main(String[] args) {
List<List<Integer>> res = new ArrayList<>();
permute(res, Arrays.asList(1, 2, 3), 0);
System.out.println(res);
}

How to populate an array till its length with some specific values from another array?

I have a function
int[ ] fill(int[ ] arr, int k, int n) that returns an array with the length n and values consists of repetition of first k elements.
My code is:
class Repeat_block {
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 3;
int n = 10;
int arr[] = { 1, 2, 3, 5, 9, 12, -2, -1 };
System.out.println(Arrays.toString(fill(arr, k, n)));
}
public static int[] fill(int[] arr, int k, int n) {
int arr2[] = new int[n];
if (k == 0 || n <= 0) {
return null;
}
for (int i = 0; i < n; i++) {
if (i <k) {
arr2[i] = arr[i];
}
}
return arr2;
}
}
The function should return 1,2,3,1,2,3,1,2,3,1
but it's returning 1, 2, 3, 0, 0, 0, 0, 0, 0, 0 . I tried with so many ideas
but could not figure out to get the right logic. Anybody with some best ideas.
Once i == k, you need to reset it to 0. Hence you need to use two loop variables.
for (int i = 0, j = 0; i < n; i++, j++) {
if (j == k) {
j = 0;
}
arr2[i] = arr[j];
}
Replace your for-loop with:
for (int i = 0; i < n; i++) {
arr2[i] = arr[i % k]
}
Try this.
public static int[] fill(int[] arr, int k, int n) {
if (k == 0 || n <= 0) {
return null;
}
int[] ret = new int[n];
int counter = 0;
int value = 1;
while (counter < n) {
if (value > k) value = 1;
ret[counter] = value;
value++;
counter++;
}
return ret;
}
I thought it will be easy using streams and I am sure that it can be done much easier but here is my poor attempt:
import java.util.*;
import java.lang.*;
import java.util.stream.Collectors;
class Main
{
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 3;
int n = 10;
int arr[] = { 1, 2, 3, 5, 9, 12, -2, -1 };
fill(arr, k, n);
}
public static void fill(int[] arr, int k, int n) {
String elementsToCopy = Arrays.stream(arr)
.limit(k)
.mapToObj(String::valueOf)
.reduce((a,b) -> a.concat(",").concat(b))
.get();
List<String> resultInList = Collections.nCopies(n, elementsToCopy);
resultInList
.stream()
.collect(Collectors.toList());
System.out.println(resultInList
.toString()
.replace(" ", "")
.replace("[", "")
.substring(0, n+n-1));
}
}
Just for practice, I done that in Python3 :
def fill(arr,k,n):
c = math.ceil(n/k)
return (arr[0:k]*c)[0:n]

A recursive algorithm to find every possible sum given an integer array?

So given an array for example [3, 5, 7, 2] I want to use recursion to give me all the possible combinations of sums, for example: 3, 5, 7, 2, 8(3+5),10(3+7),5(3+5)... 15(3+5+7) etc. I'm not exactly sure how to go about this using java.
You have two choice with each number in the array.
Use the number
Don't use the number
void foo(int[] array, int start, int sum) {
if(array.length == start) return;
int val = sum + array[start];
//print val;
foo(array, start + 1, val); //use the number
foo(array, start + 1, sum); //don't use the number
}
the initial call is foo(a, 0, 0)
An recursive algorithm for this could work as follows:
All the sums for a list equals the union of:
The first number plus the sums of the sublist without the first number
The sums of the sublist without the first number
Eventually your recursive call will hit the stopping condition of an empty list, which has only one sum(zero)
Here's one way of doing it in pseudo code:
getAllPossibleSums(list)
if(list.length == 1)
return list[0];
otherSums = getAllPossibleSums(list[1:end])
return union(
otherSums, list[0] + otherSums);
public static void main(String[] args) {
findAllSums(new int[] {3, 5, 7, 2}, 0, 0);
}
static void findAllSums(int[] arrayOfNumbers, int index, int sum) {
if (index == arrayOfNumbers.length) {
System.out.println(sum);
return;
}
findAllSums(arrayOfNumbers, index + 1, sum + arrayOfNumbers[index]);
findAllSums(arrayOfNumbers, index + 1, sum);
}
You have two branches, one in which you add the current number and another in which you don't.
public static void main(String[] args) {
int [] A = {3, 5, 7, 2};
int summation = recursiveSum(A, 0, A.length-1);
System.out.println(summation);
}
static int recursiveSum(int[] Array, int p, int q) {
int mid = (p+q)/2; //Base case
if (p>q) return 0; //Base case
else if (p==q) return Array[p];
**else
return recursiveSum(Array, p, mid) + recursiveSum(Array, mid + 1, q);**
}
Simplest way ever:
private int noOfSet;
Add below method:
private void checkSum() {
List<Integer> input = new ArrayList<>();
input.add(9);
input.add(8);
input.add(10);
input.add(4);
input.add(5);
input.add(7);
input.add(3);
int targetSum = 15;
checkSumRecursive(input, targetSum, new ArrayList<Integer>());
}
private void checkSumRecursive(List<Integer> remaining, int targetSum, List<Integer> listToSum) {
// Sum up partial
int sum = 0;
for (int x : listToSum) {
sum += x;
}
//Check if sum matched with potential
if (sum == targetSum) {
noOfSet++;
Log.i("Set Count", noOfSet + "");
for (int value : listToSum) {
Log.i("Value", value + "");
}
}
//Check sum passed
if (sum >= targetSum)
return;
//Iterate each input character
for (int i = 0; i < remaining.size(); i++) {
// Build list of remaining items to iterate
List<Integer> newRemaining = new ArrayList<>();
for (int j = i + 1; j < remaining.size(); j++)
newRemaining.add(remaining.get(j));
// Update partial list
List<Integer> newListToSum = new ArrayList<>(listToSum);
int currentItem = remaining.get(i);
newListToSum.add(currentItem);
checkSumRecursive(newRemaining, targetSum, newListToSum);
}
}
Hope this will help you.

Array even & odd sorting

I have an array where I have some numbers. Now I want to sort even numbers in a separate array and odd numbers in a separate. Is there any API to do that? I tried like this
int[] array_sort={5,12,3,21,8,7,19,102,201};
int [] even_sort;
int i;
for(i=0;i<8;i++)
{
if(array_sort[i]%2==0)
{
even_sort=Arrays.sort(array_sort[i]);//error in sort
System.out.println(even_sort);
}
}
Plain and simple.
int[] array_sort = {5, 12, 3, 21, 8, 7, 19, 102, 201 };
List<Integer> odd = new ArrayList<Integer>();
List<Integer> even = new ArrayList<Integer>();
for (int i : array_sort) {
if ((i & 1) == 1) {
odd.add(i);
} else {
even.add(i);
}
}
Collections.sort(odd);
Collections.sort(even);
System.out.println("Odd:" + odd);
System.out.println("Even:" + even);
Your question as stated doesn't make sense, and neither does the code. So I'm guessing that you want to separate the elements of an array into two arrays, one containing odds and the other evens. If so, do it like this:
int[] input = {5, 12, 3, 21, 8, 7, 19, 102, 201};
List<Integer> evens = new ArrayList<Integer>();
List<Integer> odds = new ArrayList<Integer>();
for (int i : input) {
if (i % 2 == 0) {
evens.add(i);
} else {
odds.add(i);
}
}
You can then convert a list of Integer to a sorted array if int as follows:
List<Integer> list ...
int[] array = new int[list.size()];
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}
Arrays.sort(array);
or if a sorted List<Integer> is what you need, just do this:
Collections.sort(list);
It's simple to do this using Guava.
Use Ints.asList to create a List<Integer> live view of an int[]
Define a Function<Integer,Boolean> isOdd
Use Ordering that compares onResultOf(isOdd), naturally (i.e. false first, then true)
If necessary, compound that with an Ordering.natural()
Here's the snippet:
int[] nums = {5,12,3,21,8,7,19,102,201};
Function<Integer,Boolean> isOdd = new Function<Integer,Boolean>() {
#Override
public Boolean apply(Integer i) {
return (i & 1) == 1;
}
};
Collections.sort(
Ints.asList(nums),
Ordering.natural().onResultOf(isOdd)
.compound(Ordering.natural())
);
System.out.println(Arrays.toString(nums));
// [8, 12, 102, 3, 5, 7, 19, 21, 201]
Note that all the even numbers show up first, then all the odd numbers. Within each group, the numbers are sorted naturally.
External links
polygenelubricants.com - Writing more elegant comparison logic with Guava's Ordering
There are some things to know first :
You must initialize an array before using it. For example int[] even_sort = new int[3];
In java arrays have a static size. That means that you won't be able to add as many elements as you want. You have to choose a size before. You should take a look at Java Collections, it's a good way to get rid of this "rule" the java way.
The Arrays.sort() method apply on arrays only. Here array_sort[i] is an int
Arrays.sort() sorts an array but doesn't return anything.
If you really want to use arrays (but you shouldn't) you can do something like this to resize one :
int[] even_sort = new int[3]{1, 2, 3};
int[] temp = new int[4];
System.arraycopy(even_sort, 0, temp, 0, even_sort.length);
even_sort = temp;
even_sort[3] = 4;
Another way would be creating an utility method which uses reflection to create the new array :
import java.lang.reflect.Array;
public Object resizeArray(Object originalArray, int newSize){
int originalSize = Array.getLength(originalArray);
Class arrayType = originalArray.getClass().getComponentType();
Object newArray = Array.newInstance(arrayType, newSize);
System.arraycopy(originalArray, 0, newArray, 0, Math.min(originalSize, newSize));
return newArray;
}
So if you still want to use array for some reasons (but you still shouldn't) here is a code to filter, resize and sort your array.
int[] arrayToFilterAndSort = {5, 12, 3, 21, 8, 7, 19, 102, 201};
int[] sortedEvens = new int[0];
for(int current : arrayToFilterAndSort){
if((current & 1) == 1){
sortedEvens = resizeArray(sortedEvens, sortedEvens.length + 1);
sortedEvens[sortedEvens.length - 1] = current;
}
}
Arrays.sort(sortedEvens);
Resources :
oracle.com - Arrays tutorial
oracle.com - Collections tutorial
javadoc - Arrays.sort()
package com.java.util.collection;
import java.util.Arrays;
/**
* Given n random numbers. Move all even numbers on left hand side and odd numbers on right hand side and
* then sort the even numbers in increasing order and odd numbers in decreasing order For example,
* i/p : 3 6 9 2 4 10 34 21 5
* o/p: 2 4 6 10 34 3 5 9 21
* #author vsinha
*
*/
public class EvenOddSorting {
public static void eventOddSort(int[] arr) {
int i =0;
int j =arr.length-1;
while(i<j) {
if(isEven(arr[i]) && isOdd(arr[j])) {
i++;
j--;
} else if(!isEven(arr[i]) && !isOdd(arr[j])) {
swap(i,j,arr);
} else if(isEven(arr[i])){
i++;
} else{
j--;
}
}
display(arr);
// even number sorting
Arrays.sort(arr,0,i);
Arrays.sort(arr,i,arr.length);
// odd number sorting
display(arr);
}
public static void display(int[] arr) {
System.out.println("\n");
for(int val:arr){
System.out.print(val +" ");
}
}
private static void swap(int pos1, int pos2, int[] arr) {
int temp = arr[pos1];
arr[pos1]= arr[pos2];
arr[pos2]= temp;
}
public static boolean isOdd(int i) {
return (i & 1) != 0;
}
public static boolean isEven(int i) {
return (i & 1) == 0;
}
public static void main(String[] args) {
int arr[]={3, 6, 9 ,2, 4, 10, 34, 21, 5};
eventOddSort(arr);
}
}
int arr[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
cout << "The Even no are : \n";
for (int i = 1; i <= 10; i++) // for start for only i....(even nos)
{
if (i % 2 == 0)
{
cout << i;
cout << " ";
}
}
cout << "\nThe Odd no are : \n";
for (int j = 1; j <= 10; j++) // for start for only j....(odd nos)
{
if (j % 2 != 0)
{
cout << j;
cout << " ";
}`enter code here`
}
package srikanth dukuntla;
public class ArrangingArray {
public static void main(String[] args) {
int j=0;
int []array={1,2,3,5,4,55,32,0};
System.out.println(array.length);
int n=array.length/2;
for (int i=0; i<array.length; i++){
if(array[i]%2!=0){
j=1;
int temp=array[array.length-j];
if(temp % 2!=0){
while((array[array.length-(j+1)]%2!=0) && (array.length-(j+1)>n)){
j++;
}
int temp2=array[array.length-(j+1)];
array[array.length-(j+1)] =array[i];
array[i]=temp2;
}else // inner if
{
array[array.length-j] =array[i];
array[i]=temp;
}
}else //main if
{
//nothing needed
}
}
for(int k=0;k<array.length;k++) {
System.out.print(" "+ array[k]);
}
}
}
List < Integer > odd = new ArrayList < Integer > ();
List < Integer > even = new ArrayList < Integer > ();
int a [] = {0,2,3,98,1,6546,45323,1134564};
int i;
for (i = 0; i < a.length; i++) {
if (a[i] % 2 == 0) {
even.add(a[i]);
} else {
odd.add(a[i]);
}
}
System.out.print("Even: " + even + "\n");
System.out.print("Uneven: " + odd + "\n");
}
}

Categories

Resources