import java.util.*;
public class RotateList {
public static void main(String[] args)
{
List<List<Integer>> copies = new ArrayList<>();
List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3));
int size = list.size();
Set<List<Integer>> set = new HashSet<>();
while(size > 0)
{
copies.add(list);
size--;
}
size = list.size();
System.out.println("Copies Before:");
System.out.println(copies);
for(int i = 0; i < copies.size();i++)
{
Collections.rotate(copies.get(i), i+1);
}
System.out.println("Copies after:");
System.out.println(copies);
}
}
The output is:
Copies Before: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
Copies after: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
I don't know where I'm going wrong with this.
The problem is that you are adding the same list 3 times. When you rotate one of them, you rotate all of them.
You must create 3 separate lists.
List<List<Integer>> copies = new ArrayList<>();
for(int i = 0; i < 3; i++) {
copies.add(new ArrayList<>(Arrays.asList(1,2,3)));
}
System.out.println("Copies Before:");
System.out.println(copies);
for (int i = 0; i < copies.size(); i++) {
Collections.rotate(copies.get(i), i + 1);
}
System.out.println("Copies after:");
System.out.println(copies);
Output:
Copies Before:
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
Copies after:
[[3, 1, 2], [2, 3, 1], [1, 2, 3]]
Related
It's a combinatorics problem. We can partition the array at max n-1 times and out of it, we have to choose k-1 partitions.
Ex: arr[] = {1, 2, 3, 4, 5, 6}
k = 3, n = 6.
Total possibilities = (n-1)C(k-1) 5C2 = 10.
Expected Output : (3-dimensional array)
[
[[1], [2], [3, 4, 5, 6]],
[[1], [2, 3], [4, 5, 6]],
[[1], [2, 3, 4], [5, 6]],
[[1], [2, 3, 4, 5], [6]],
[[1, 2], [3], [4, 5, 6]],
[[1, 2], [3, 4], [5, 6]],
[[1, 2], [3, 4, 5], [6]],
[[1, 2, 3], [4, 5], [6]],
[[1, 2, 3, 4], [5], [6]],
]
Constraints:
Subarrays should have at least 1 element.
SubArrays should only consist of consecutive elements.
For ex: [[1, 3], [2, 4], [5, 6]] This is not valid.
So far, I have tried a recursive method but it yields wrong results. I can't wrap my head around how to correct it. I need an answer explaining how to approach this problem properly and the intuition behind it first and then correct my code and point out where I went wrong.
My code:
public static void main(String[] args) {
int n = 6;
int k = 3;
int[] arr = new int[]{1,2,3,4,5,6};
ArrayList<ArrayList<ArrayList<Integer>>> result = new ArrayList<ArrayList<ArrayList<Integer>>>();
ArrayList<ArrayList<Integer>> eachComb = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> eachSubArray = new ArrayList<Integer>();
int index = 0;
generateCombinations(arr, k, index, eachSubArray, eachComb, result);
for (ArrayList<ArrayList<Integer>> each : result) {
for(ArrayList<Integer> eachh: each) {
System.out.println(eachh);
}
System.out.println("-------------------------------");
}
}
private static void generateCombinations(int[] arr, int k, int index, ArrayList<Integer> eachSubArray,
ArrayList<ArrayList<Integer>> eachComb, ArrayList<ArrayList<ArrayList<Integer>>> result) {
if(k==0 || index==arr.length) {
return;
}
if(!eachSubArray.isEmpty()) {
eachComb.add(new ArrayList<>(eachSubArray));
}
if(k==1) {
ArrayList<Integer> last = new ArrayList<Integer>();
for(int i=index; i<arr.length; i++) {
last.add(arr[i]);
}
if(!last.isEmpty()) {
eachComb.add((last));
result.add(new ArrayList<ArrayList<Integer>>(eachComb));
eachComb.remove(eachComb.size()-1);
}
return;
}
eachSubArray.clear();
for(int i=index; i<arr.length; i++) {
eachSubArray.add((arr[i]));
generateCombinations(arr, k-1, i+1, eachSubArray, eachComb, result);
if(!eachComb.isEmpty()) {
eachComb.remove(eachComb.size()-1);
}
}
}
static List<List<Integer>> finalSubset = new ArrayList<>();
public static void main(String[] args) {
ArrayList<Integer> a = new ArrayList<>();
Integer[] array = {1, 2 ,3};
Collections.addAll(a, array);
subsets(a, 0);
System.out.println(finalSubset);
}
static void subsets (ArrayList<Integer> arr, int pos) {
if (arr.size() == 0) return;
finalSubset.add(arr); //problem
for (int i = pos; i < arr.size(); i++) {
Integer temp = arr.get(i);
arr.remove (i);
subsets(arr, i);
arr.add(i, temp);
}
}
I've tried out to make a code that prints out all possible subsets of given array using ArrayList and when I run it output is correct, but when I substitute System.out.println(arr) by funalSubset.add(arr) the output is:
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
when it needs to be:
[1, 2, 3], [2, 3], [3], [2], [1, 3], [1], [1, 2], []
what's the reason of such output?
You are adding the same array list to finalSubset many times. You should create a copy every time you recurse, either when you add to finalSubset:
finalSubset.add(new ArrayList<>(arr));
OR when you do the recursive call:
subsets(new ArrayList<>(arr), i);
This way you have different lists that can have different things inside. If you only have one list, you just get the same thing repeated 8 times.
Also, you should add to finalSubset before you return, otherwise the empty list won't be added to finalSubset.
finalSubset.add(new ArrayList<>(arr));
if (arr.size() == 0) return;
I am creating unique subsequences of size 2 using below code. How can I create subsequences of different sizes. Size would be dynamic.
For example, [1 2 3 4] -> [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
For size 3, it would be , [[1, 2, 3], [1, 2, 4], [2, 3, 4]]
public static int getTheSubseq(List<Integer> AList){
List<List<Integer>> li = new ArrayList<>();
for (int i = 0; i < AList.size(); i++){
for(int j =i+1; j < AList.size(); j++){
List<Integer> temp = new ArrayList<>();
temp.add(AList.get(i));
temp.add(AList.get(j));
li.add(temp);
}
}
System.out.println(li);
return 1;
}
Using recursion you could build the subsequences as follows:
private void buildSubsequence( List<Integer> source, int targetSize,
List<List<Integer>> result, Stack<Integer> currentSubsequence, int currentIndex ) {
//We don't want to iterate beyond the point where we can't build a complete subsequence.
//Thus we'll need to subtract the number of still needed elements
//(target count - number of elements already in the subsequence - 1 for this call)
int maxIndex = source.size() - ( targetSize - currentSubsequence.size() - 1);
//iterate over each index from the current one to this call's max
for( int i = currentIndex; i < maxIndex; i++ ) {
//add the element at that index to the subsequence
currentSubsequence.push( source.get( i ) );
//if we're done make a copy
if( currentSubsequence.size() == targetSize ) {
result.add( new ArrayList<Integer>( currentSubsequence) );
} else { //if we're not done, get the next element
buildSubsequence( source, targetSize, result, currentSubsequence, i + 1 );
}
//remove the last element added by push() to have it replaced with the next one
currentSubsequence.pop();
}
}
Then you call it like this:
List<Integer> source = Arrays.asList( 1,2,3,4,5,6 );
List<List<Integer>> result = new LinkedList<>();
buildSubsequence( source, 3, result, new Stack<>(), 0 );
That creates the following subsequences:
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 2, 6]
[1, 3, 4]
[1, 3, 5]
[1, 3, 6]
[1, 4, 5]
[1, 4, 6]
[1, 5, 6]
[2, 3, 4]
[2, 3, 5]
[2, 3, 6]
[2, 4, 5]
[2, 4, 6]
[2, 5, 6]
[3, 4, 5]
[3, 4, 6]
[3, 5, 6]
[4, 5, 6]
Note that this is just one way to solve it. :)
I'm a beginner in programming and I have a method :
public int[][] toArray(List<Integer> list, int rows) {
int[][] result = new int[list.size()][rows];
int i = 0;
int j = 0;
for (Integer value : list) {
result[i][j] = value;
j++;
if(j > rows - 1){
i++;
j = 0;
}
}
return result;
}
The result of it, if rows = 2 (and if we have a list contains numbers from 1 to 7) is:
[[1, 2], [3, 4], [5, 6], [7, 0], [0, 0], [0, 0], [0, 0]]
If rows = 3 result is:
[[1, 2, 3], [4, 5, 6], [7, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
What I need:
[[1, 2], [3, 4], [5, 6], [7, 0]]
[[1, 2, 3], [4, 5, 6], [7, 0, 0]]
How to do that?
Just for fun, here's another approach using Streams and Guava:
public static int[][] toArray(List<Integer> list, int rows) {
return Lists.partition(list, rows)
.stream()
.map(Ints::toArray)
.map(a -> Arrays.copyOf(a, rows))
.toArray(int[][]::new);
}
The problem lies in this line of code:
int[][] result = new int[list.size()][rows];
As you are initializing the result to a 2D array having rows equals to list.size() you are getting always seven rows. The solution is to first compute the number of rows for result array properly and then initialize it.
int resultRows = list.size()/rows;
if(list.size()%rows!=0){
resultRows++;
}
int[][] result = new int[resultRows][rows];
You can use a counter to track the count and determine the position by counter/rows and counter%rows, e.g.:
public int[][] toArray(List<Integer> list, int rows) {
int[][] result = new int[list.size()][rows];
int counter = 0;
for (Integer value : list) {
result[counter/rows][counter%rows] = value;
counter++;
}
return result;
}
You don't need to worry about remaining places as all the MxN elements get initialised with 0 when you declare an array with size.
I have n lists, for example:
L_1 = [a_11, a_12, ...]
L_2 = [a_21, a_22, ...]
...
L_n = [a_n1, a_n2, ...]
where ith list has k_i elements.
And now, I want to generate all n-elements list, where ith element is from L_i, I mean:
[a_11, a_21, ..., a_n1]
[a_11, a_21, ..., a_n2]
...
[a_11, a_22, ..., a_n1]
[a_11, a_22, ..., a_n2]
...
[a_12, a_21, ..., a_n1]
[a_12, a_21, ..., a_n2]
...
[a_12, a_22, ..., a_n1]
[a_12, a_22, ..., a_n2]
...
The total number of lists shoulbe be equal to k_1*k_2*...k_n. Could you describe pseudo-code of this algorithm or use Java code? I can do this using nested for-loops when number of lists is hardcoded, but I'm completely blocked when n is customizable at runtime.
Ok, I implemented this algorithm.
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PermutationGenerator {
private List<List<Integer>> result;
private List<List<Integer>> data;
public List<List<Integer>> permutate(List<List<Integer>> data) {
this.data = data;
this.result = Lists.newArrayList();
List<Integer> integers = new ArrayList<Integer>(Collections.nCopies(data.size(), 0));
foo(0, data.size() - 1, integers);
return result;
}
private void foo(Integer index, Integer maxIndex, List<Integer> output) {
List<Integer> list = data.get(index);
for (int i = 0; i < list.size(); i++) {
output.set(index, list.get(i));
if (index == maxIndex) {
result.add(Lists.newArrayList(output));
} else {
foo(index + 1, maxIndex, output);
}
}
}
}
Test class:
import com.google.common.collect.Lists;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class PermutationGeneratorTest {
#Test
public void test() throws Exception {
// given
PermutationGenerator pg = new PermutationGenerator();
List<Integer> list1 = Lists.newArrayList(1, 2, 3);
List<Integer> list2 = Lists.newArrayList(4, 5);
List<Integer> list3 = Lists.newArrayList(6, 7, 8, 9);
List<List<Integer>> input = Lists.newArrayList(list1, list2, list3);
// when
List<List<Integer>> output = pg.permutate(input);
// then
print(output);
}
private void print(List<List<Integer>> output) {
for (List<Integer> list : output) {
System.out.println(Arrays.toString(list.toArray()));
}
System.out.println("TOTAL: " + output.size());
}
}
Output:
[1, 4, 6]
[1, 4, 7]
[1, 4, 8]
[1, 4, 9]
[1, 5, 6]
[1, 5, 7]
[1, 5, 8]
[1, 5, 9]
[2, 4, 6]
[2, 4, 7]
[2, 4, 8]
[2, 4, 9]
[2, 5, 6]
[2, 5, 7]
[2, 5, 8]
[2, 5, 9]
[3, 4, 6]
[3, 4, 7]
[3, 4, 8]
[3, 4, 9]
[3, 5, 6]
[3, 5, 7]
[3, 5, 8]
[3, 5, 9]
TOTAL: 24
As you have already found out yourself, the usual trick is to think of the lists a non-uniform version of the g-adic numbers and do carry increment on the list index positions:
When you have n lists, you have n index positions in those lists:
index_pos = [i0, ..., in-1]
The trick is now as follows:
start with index_pos = [0, 0, ...]
increment index_pos[0].
If the result is larger or equal to lists[0].size(), set index_pos[0] = 0 and increment index_pos[1].
if index_pos[1] is larger than or equal to lists[1].size() ... and so on
You are done when index_pos[n - 1] overflows
An non-recursive solution in Java would be like
public static <T> void permute(
final List<List<T>> lists,
final Consumer<List<T>> consumer
)
{
final int[] index_pos = new int[lists.size()];
final int last_index = lists.size() - 1;
final List<T> permuted = new ArrayList<T>(lists.size());
for (int i = 0; i < lists.size(); ++i) {
permuted.add(null);
}
while (index_pos[last_index] < lists.get(last_index).size()) {
for (int i = 0; i < lists.size(); ++i) {
permuted.set(i, lists.get(i).get(index_pos[i]));
}
consumer.accept(permuted);
for (int i = 0; i < lists.size(); ++i) {
++index_pos[i];
if (index_pos[i] < lists.get(i).size()) {
/* stop at first element without overflow */
break;
} else if (i < last_index) {
index_pos[i] = 0;
}
}
}
}
Usage example:
public static void main(String[] args)
{
final List<List<Integer>> lists = new ArrayList<List<Integer>>();
final List<Integer> list0 = new ArrayList<Integer>();
list0.add(0);
list0.add(1);
list0.add(2);
list0.add(4);
lists.add(list0);
lists.add(list0);
lists.add(list0);
permute(lists, (permutation -> System.out.println(permutation)));
}