Printing all possible subsets of a list - java

I have a List of elements (1, 2, 3), and I need to get the superset (powerset) of that list (without repeating elements). So basically I need to create a List of Lists that looks like:
{1}
{2}
{3}
{1, 2}
{1, 3}
{2, 3}
{1, 2, 3}
What is the best (simplicity > efficiency in this case, the list won't be huge) way to implement this? Preferably in Java, but a solution in any language would be useful.

Use bitmasks:
int allMasks = (1 << N);
for (int i = 1; i < allMasks; i++)
{
for (int j = 0; j < N; j++)
if ((i & (1 << j)) > 0) //The j-th element is used
System.out.print((j + 1) + " ");
System.out.println();
}
Here are all bitmasks:
1 = 001 = {1}
2 = 010 = {2}
3 = 011 = {1, 2}
4 = 100 = {3}
5 = 101 = {1, 3}
6 = 110 = {2, 3}
7 = 111 = {1, 2, 3}
You know in binary the first bit is the rightmost.

import java.io.*;
import java.util.*;
class subsets
{
static String list[];
public static void process(int n)
{
int i,j,k;
String s="";
displaySubset(s);
for(i=0;i<n;i++)
{
for(j=0;j<n-i;j++)
{
k=j+i;
for(int m=j;m<=k;m++)
{
s=s+m;
}
displaySubset(s);
s="";
}
}
}
public static void displaySubset(String s)
{
String set="";
for(int i=0;i<s.length();i++)
{
String m=""+s.charAt(i);
int num=Integer.parseInt(m);
if(i==s.length()-1)
set=set+list[num];
else
set=set+list[num]+",";
}
set="{"+set+"}";
System.out.println(set);
}
public static void main()
{
Scanner sc=new Scanner(System.in);
System.out.println("Input ur list");
String slist=sc.nextLine();
int len=slist.length();
slist=slist.substring(1,len-1);
StringTokenizer st=new StringTokenizer(slist,",");
int n=st.countTokens();
list=new String[n];
for(int i=0;i<n;i++)
{
list[i]=st.nextToken();
}
process(n);
}
}

A java solution based on Petar Minchev solution -
public static List<List<Integer>> getAllSubsets(List<Integer> input) {
int allMasks = 1 << input.size();
List<List<Integer>> output = new ArrayList<List<Integer>>();
for(int i=0;i<allMasks;i++) {
List<Integer> sub = new ArrayList<Integer>();
for(int j=0;j<input.size();j++) {
if((i & (1 << j)) > 0) {
sub.add(input.get(j));
}
}
output.add(sub);
}
return output;
}

In the given solution we iterate over every index and include current and all further elements.
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
if(nums == null || nums.length ==0){
return ans;
}
Arrays.sort(nums);
List<Integer> subset = new ArrayList<>();
allSubset(nums, ans , subset , 0);
return ans;
}
private void allSubset(int[] nums,List<List<Integer>> ans ,List<Integer> subset , int idx){
ans.add(new ArrayList<>(subset));
for(int i = idx; i < nums.length; i++){
subset.add(nums[i]);
allSubset(nums, ans , subset , i+1);
subset.remove(subset.size() - 1);
}
}
}

I've noticed that answers are focused on the String list.
Consequently, I decided to share more generic answer.
Hope it'll be fouund helpful.
(Soultion is based on another solutions I found, I combined it to a generic algorithem.)
/**
* metod returns all the sublists of a given list
* the method assumes all object are different
* no matter the type of the list (generics)
* #param list the list to return all the sublist of
* #param <T>
* #return list of the different sublists that can be made from the list object
*/
public static <T> List<List<T>>getAllSubLists(List<T>list)
{
List<T>subList;
List<List<T>>res = new ArrayList<>();
List<List<Integer>> indexes = allSubListIndexes(list.size());
for(List<Integer> subListIndexes:indexes)
{
subList=new ArrayList<>();
for(int index:subListIndexes)
subList.add(list.get(index));
res.add(subList);
}
return res;
}
/**
* method returns list of list of integers representing the indexes of all the sublists in a N size list
* #param n the size of the list
* #return list of list of integers of indexes of the sublist
*/
public static List<List<Integer>> allSubListIndexes(int n) {
List<List<Integer>> res = new ArrayList<>();
int allMasks = (1 << n);
for (int i = 1; i < allMasks; i++)
{
res.add(new ArrayList<>());
for (int j = 0; j < n; j++)
if ((i & (1 << j)) > 0)
res.get(i-1).add(j);
}
return res;
}

This is the simple function can be used to create a list of all the possible numbers generated by digits of all possible subsets of the given array or list.
void SubsetNumbers(int[] arr){
int len=arr.length;
List<Integer> list=new ArrayList<Integer>();
List<Integer> list1=new ArrayList<Integer>();
for(int n:arr){
if(list.size()!=0){
for(int a:list){
list1.add(a*10+n);
}
list1.add(n);
list.addAll(list1);
list1.clear();
}else{
list.add(n);
}
}
System.out.println(list.toString());
}

Peter Minchev's solution modified to handle larger lists through BigInteger
public static List<List<Integer>> getAllSubsets(List<Integer> input) {
BigInteger allMasks = BigInteger.ONE.shiftLeft(input.size());
List<List<Integer>> output = new ArrayList<>();
for(BigInteger i=BigInteger.ZERO;allMasks.subtract(i).compareTo(BigInteger.ZERO)>0; i=i.add(BigInteger.ONE)) {
List<Integer> subList = new ArrayList<Integer>();
for(int j=0;j<input.size();j++) {
if(i.and(BigInteger.valueOf(1<<j)).compareTo(BigInteger.ZERO) > 0) {
subList.add(input.get(j));
}
}
System.out.println(subList);
output.add(subList);
}
return output;
}

/*---USING JAVA COLLECTIONS---*/
/*---O(n^3) Time complexity, Simple---*/
int[] arr = new int[]{1,2,3,4,5};
//Convert the array to ArrayList
List<Integer> arrList = new ArrayList<>();
for(int i=0;i<arr.length;i++)
arrList.add(arr[i]);
List<List<Integer>> twoD_List = new ArrayList<>();
int k=1; /*-- k is used for toIndex in sublist() method---*/
while(k != arr.length+1) /*--- arr.length + 1 = toIndex for the last element---*/
{
for(int j=0;j<=arr.length-k;j++)
{
twoD_List.add(arrList.subList(j, j+k));/*--- fromIndex(j) - toIndex(j+k)...notice that j varies till (arr.length - k), while k is constant for the whole loop...k gets incremented after all the operations in this for loop---*/
}
k++; /*--- increment k for extending sublist(basically concept the toIndex)---*/
}
//printing all sublists
for(List<Integer> list : twoD_List) System.out.println(list);

Related

Is there a way to add a HashMap's value that is a integer array into a ArrayList?

I'm doing this leetcode problem: https://leetcode.com/problems/find-k-pairs-with-smallest-sums/
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.
Define a pair (u,v) which consists of one element from the first array
and one element from the second array.
Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.
Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
Output: [[1,2],[1,4],[1,6]]
Explanation: The first 3 pairs are returned from the sequence:
[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
So my thinking process is to use a HashMap, and a Heap. My HashMap's key is the sum of 2 array's index values. And the value, I will put the 2 values that add up to the sum.
Then I add the sums into the heap, then pop it out K times. That will give me the lowest sums.
Now my problem is that when I try to add the hashmap's value into an ArrayList, it gives me an error. Below is what I have tried.
public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> list = new ArrayList<>();
HashMap<Integer, int[]> map = new HashMap<>();
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
int sum = nums1[i] + nums2[j];
map.put(sum, new int[]{nums1[i], nums2[j]});
minHeap.offer(sum);
}
}
for (int i = 0; i < k; i++) {
int key = minHeap.poll();
//list.add(map.get(key)); // ERRORRR
list.add(map.get(key)[0]); //gets the first value associated with key
list.add(map.get(key)[1]); // gets the second value associated with key
}
ans.add(list);
return ans;
}
After researching, the error is because the arraylist has Integer values while my HashMap, I put it as int[]. After searching a bit more, I found
list.add(map.get(key)[0]);
list.add(map.get(key)[1]);
But after doing this, I got the list to show up as: [[1,2,1,4,1,6]].
But I want the answer as: [[1,2],[1,4],[1,6]].
Is there any way to get my list to keep adding a new list? If that makes sense.
Thank you, everyone!
You may use directly List<Integer> as value of your map to get it easily and put it directly into the result List :
static List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
List<List<Integer>> ans = new ArrayList<>();
HashMap<Integer, List<Integer>> map = new HashMap<>();
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int val1 : nums1) {
for (int val2 : nums2) {
int sum = val1 + val2;
map.put(sum, Arrays.asList(val1, val2));
minHeap.offer(sum);
}
}
for (int i = 0; i < k; i++) {
int key = minHeap.poll();
ans.add(map.get(key));
}
return ans; // [[1, 2], [1, 4], [1, 6]]
}
With Java 8 Stream you could even add a shorter way for the loop at the end (replace the for-i loop)
return IntStream.range(0, k).map(e -> minHeap.poll()).mapToObj(map::get)
.collect(Collectors.toList());
And when you get crazy with Stream and don't really care about performances, you could do ... :
import static java.util.Arrays.asList;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.of;
static List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
return of(nums1)
.mapToObj(v1 -> of(nums2).mapToObj(v2 -> asList(v1, v2)).collect(toList()))
.flatMap(List::stream)
.sorted(comparingInt(o -> o.stream().mapToInt(i -> i).sum()))
.limit(k).collect(toList());
}
The issue is because you are using same instance of ‘list’ variable. Because of same instance all the values from map are adding in a same list and that’s why in output you are getting only one list.
Fix:
for (int i = 0; i < k; i++) {
List<Integer> list = new ArrayList<>();
int key = minHeap.poll();
//list.add(map.get(key)); // ERRORRR
list.add(map.get(key)[0]); //gets the first value associated with key
list.add(map.get(key)[1]); // gets the second value associated with key
ans.add(list);
}
Put ans.add(list) inside the for loop.
Put the result values direct into ans.add(map.get(key));
Remove the List<Integer> list = new ArrayList<>();
Change the signature of public static List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k)
public static void main(String[] args) {
kSmallestPairs(new int[]{1, 7, 11}, new int[]{2, 4, 6}, 3)
.forEach(list -> System.out.print(Arrays.toString(list)));
}
// Change the return type from List<List<Integer>> to List<int[]>
public static List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
List<int[]> ans = new ArrayList<>();
// Remove the unused list
HashMap<Integer, int[]> map = new HashMap<>();
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
int sum = nums1[i] + nums2[j];
map.put(sum, new int[]{nums1[i], nums2[j]});
minHeap.offer(sum);
}
}
for (int i = 0; i < k; i++) {
int key = minHeap.poll();
// Put the value into ans
ans.add(map.get(key));
}
return ans;
}
Output
[1, 2][1, 4][1, 6]
You can achieve the output with little change in for loop.
for (int i = 0; i < k; i++) {
int key = minHeap.poll();
list = new ArrayList<>();
list.add(map.get(key)[0]);
list.add(map.get(key)[1]);
ans.add(list);
}
Just Create new Object in start of loop and in list at the end of each loop.

Two Sum LeetCode Java Questions

I am attempting a Java mock interview on LeetCode. I have the following problem:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
I was attempting to implement a recursive solution. However, I am receiving errors upon trying to run my code.
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] sumnums = nums.clone();
//int[2] sol = {0,1};
int[] sol = new int[]{0,1};
sol = new int[2];
int j=sumnums.length;
int t=target;
for(int i=0;i<sumnums.length;i++){
if ((sumnums[i]+sumnums[j])==t){
sol[0]=i;
sol[1]=j;
//return sol;
}
}
j=j-1;
twoSum(sumnums,t);
return sol;
}
}
Error(s):
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Solution.twoSum(Solution.java:12)
at __DriverSolution__.__helper__(__Driver__.java:8)
at __Driver__.main(__Driver__.java:54)
It appears to me the error may have to do with the following line of code:
if ((sumnums[i]+sumnums[j])==t){
Therefore, I am wondering if this is a syntax related error. I am attempting to check to see if two numbers add up to a different number.
Since this is a naive attempt at a recursive solution, I am happy to take any other criticism. But I am mostly concerned with getting my attempt at this problem to work and run with all testcases.
Thanks.
METHOD 1. Naive approach: Use two for loops
The naive approach is to just use two nested for loops and check if the sum of any two elements in the array is equal to the given target.
Time complexity: O(n^2)
// Time complexity: O(n^2)
private static int[] findTwoSum_BruteForce(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return new int[] { i, j };
}
}
}
return new int[] {};
}
METHOD 2. Use a HashMap (Most efficient)
You can use a HashMap to solve the problem in O(n) time complexity. Here are the steps:
Initialize an empty HashMap.
Iterate over the elements of the array.
For every element in the array -
If the element exists in the Map, then check if it’s the complement (target - element) also exists in the Map or not. If the complement exists then return the indices of the current element and the complement.
Otherwise, put the element in the Map, and move to the next iteration.
Time complexity: O(n)
// Time complexity: O(n)
private static int[] findTwoSum(int[] nums, int target) {
Map<Integer, Integer> numMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (numMap.containsKey(complement)) {
return new int[] { numMap.get(complement), i };
} else {
numMap.put(nums[i], i);
}
}
return new int[] {};
}
METHOD 3. Use Sorting along with the two-pointer sliding window approach
There is another approach which works when you need to return the numbers instead of their indexes. Here is how it works:
Sort the array.
Initialize two variables, one pointing to the beginning of the array (left) and another pointing to the end of the array (right).
Loop until left < right, and for each iteration
if arr[left] + arr[right] == target, then return the indices.
if arr[left] + arr[right] < target, increment the left index.
else, decrement the right index.
This approach is called the two-pointer sliding window approach. It is a very common pattern for solving array related problems.
Time complexity: O(n*log(n))
// Time complexity: O(n*log(n))
private static int[] findTwoSum_Sorting(int[] nums, int target) {
Arrays.sort(nums);
int left = 0;
int right = nums.length - 1;
while(left < right) {
if(nums[left] + nums[right] == target) {
return new int[] {nums[left], nums[right]};
} else if (nums[left] + nums[right] < target) {
left++;
} else {
right--;
}
}
return new int[] {};
}
Why not use a HashMap? Here is how it will work. We will iterate through the array and check if the target - nums[i] exists in the map. If not, we will store Key, Value as the number and its index respectively i.e K = nums[i], V = i
Here is how it will work:
Consider nums = [2, 7, 11, 15], target = 9
We will start iterating the array
First comes 2. Here we will check ( 9 - 2 ) i.e 7 does not exist in the hashmap, so we will store 2 as key and its index 0 as its value
Then, comes 7. Here we will check ( 9 - 7 ) i.e 2 which exists in the map and so we will return the index of 2 and index of 7 i.e returning [ 0, 1 ]
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++)
{
if(map.containsKey(target - nums[i]))
{
return new int[] {map.get(target-nums[i]),i};
}
else
map.put(nums[i],i);
}
return new int[] {-1,-1};
}
As you mentioned
First comes 2. Here we will check ( 9 - 2 ) i.e 7 does not exist in the hashmap
actually 7 does exist in the HashMap right
nums = [2, 7, 11, 15], target = 9
public static int[] twoSum(int[] nums, int target) {
int[] sumnums = nums.clone();
//int[2] sol = {0,1};
int[] sol = new int[]{0,1};
sol = new int[2];
int j=sumnums.length; // Every recursion j will be initialized as sumnums.length instead of J-1
int t=target;
for(int i=0;i<sumnums.length;i++){
// if ((sumnums[i]+sumnums[j])==t){
// Remember that Java arrays start at index 0, so this value(sumnums[j]) is not exist in the array.
if ((sumnums[i]+sumnums[j-1])==t){
sol[0]=i;
sol[1]=j;
return sol;
}
}
j=j-1;
twoSum(sumnums,t);
return sol;
}
One of the many possible solutions:
public class TwoSumIndex {
public static void main(String... args) {
int[] arr = {2, 7, 11, 15, 9, 0, 2, 7};
System.out.println(findTwoSums(arr, 9));
}
private static List<List<Integer>> findTwoSums(int[] arr, int target) {
Set<Integer> theSet = Arrays.stream(arr).mapToObj(Integer::valueOf).collect(Collectors.toSet());
List<Integer> arrList = Arrays.stream(arr).mapToObj(Integer::valueOf).collect(Collectors.toList());
List<Pair<Integer, Integer>> theList = new ArrayList<>();
List<Integer> added = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
int a = target - arr[i];
if (theSet.contains(a) && added.indexOf(i) < 0) { // avoid duplicates;
Integer theOther = arrList.indexOf(a);
theList.add(new Pair(i, theOther));
added.add(i);
added.add(theOther);
}
}
return theList.stream().map(pair -> new ArrayList<>(Arrays.asList(pair.getKey(), pair.getValue())))
.collect(Collectors.toList());
}
}
There are several things you need to know:
duplicates in the input array are allowed;
un-ordered array in the input is allowed;
no index pair duplicate in the output;
time complexity is theoretically O(N^2) but actually will be much lower since theSet.contains(a) O(logN) will filter out all failed indexes and then do the index duplicate O(N) checking, so the actual time complexity should be O(NlogN);
The output for the demo:
[[0, 1], [4, 5], [6, 1], [7, 0]]
I use the simpler approch
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indices= new int[2];
int len=nums.length;
for(int i=0; i<len; i++){
for(int j=i+1; j<len;j++){
if((nums[i]+nums[j])==target){
indices[0] = i;
indices[1] = j;
return indices;
}
}
}
return null;
}
}
Complete code for beginners
//Predefined values
import java.util.Arrays;
public class TwoSum {
public static void main(String args[]) {
Solution solution = new Solution();
int target = 9;
int num[] = {2, 7, 11, 15};
num = solution.twoSum(num, target);
System.out.println(Arrays.toString(num));
}
}
class Solution {
public int[] twoSum(int[] nums, int target) {
int result[] = new int[2];
int sum;
for (int i = 0; i + 1 < nums.length; i++) {
// adding the alternate numbers
sum = nums[i] + nums[i + 1];
if (sum == target) {
result[0] = i;
result[1] = i + 1;
return result;
}
}
return null;
}
}
************************************************************************
//User-defined
import java.util.Arrays;
import java.util.Scanner;
/**
*
* #author shelc
*/
public class TwoSum {
public static void main(String[] args) {
Solution solution = new Solution();
Scanner scanner = new Scanner(System.in);
int n;
System.out.print("Enter the number of elements : ");
n = scanner.nextInt();
int array[] = new int[10];
System.out.println("Enter the array elemets : ");
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int target;
System.out.println("Enter the target : ");
target = scanner.nextInt();
int nums[] = solution.twoSum(array, target);
System.out.println(Arrays.toString(nums));
}
}
class Solution {
public int[] twoSum(int nums[], int target) {
int result[] = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if ((nums[i] + nums[j]) == target) {
result[0] = i;
result[1] = j;
return result;
}
}
}
return null;
}
}
public static int[] twoSum(int[] nums, int target) {
int[] arr = new int[2];
int arrIndex =0;
for(int i =0; i<nums.length; i++){
for(int j = 0;j<nums.length-1;j++){
if( i!=j) {// don't check to itself
if (nums[i] + nums[j] == target) {
arr[arrIndex] = i;
arr[arrIndex + 1] = j;
break;
}
}
}
}
Arrays.sort(arr);
return arr;
}

Print all subsets of an array recursively

I want to print all subsets of the generated arrays recursively in the main method.
The following lines show my Code. I don't know how to implement the method subsets() recursively.
public class Main {
// Make random array with length n
public static int[] example(int n) {
Random rand = new Random();
int[] example = new int[n + 1];
for (int i = 1; i <= n; i++) {
example[i] = rand.nextInt(100);
}
Arrays.sort(example, 1, n + 1);
return example;
}
// Copy content of a boolean[] array into another boolean[] array
public static boolean[] copy(boolean[] elements, int n) {
boolean[] copyof = new boolean[n + 1];
for (int i = 1; i <= n; i++) {
copyof[i] = elements[i];
}
return copyof;
}
// Counts all subsets from 'set'
public static void subsets(int[] set, boolean[] includes, int k, int n) {
// recursive algo needed here!
}
public static void main(String[] args) {
// index starts with 1, -1 is just a placeholder.
int[] setA = {-1, 1, 2, 3, 4};
boolean[] includesA = new boolean[5];
subsets(setA, includesA, 1, 4);
}
}
Here's a non-recursive technique:
public List<Set<Integer>> getSubsets(Set<Integer> set) {
List<Set<Integer>> subsets = new ArrayList<>();
int numSubsets = 1 << set.size(); // 2 to the power of the initial set size
for (int i = 0; i < numSubsets; i++) {
Set<Integer> subset = new HashSet<>();
for (int j = 0; j < set.size(); j++) {
//If the jth bit in i is 1
if ((i & (1 << j)) == 1) {
subset.add(set.get(i));
}
}
subsets.add(subset);
}
return subsets;
}
If you want only unique (and usually unordered) subsets, use a Set<Set<Integer>> instead of List<Set<Integer>>.
If it's an option to use a third party library, the Guava Sets class can give you all the possible subsets. Check out the powersets method.

Adding from ArrayList to another ArrayList from a given index

I have two arraylist
private final ArrayList children = new ArrayList();
private final ArrayList values = new ArrayList();
I have a method which when called with a value(index number) should fill the children arrayList taking values from the values ArrayList starting at the given index i and filling it circularly.
private void populateList(int i)
{
children.clear();
// A logic to add list in this form as shown in the above picture.
children.add(values.get(i));
children.add(values.get(i + 1));
...
}
I need a logic that will copy the values from the values arrayList to children arrayList with best performance in a circular order from the given index.
You can use a simple for loop. At each iteration you get the value at index i, then increment the index to get the next value.
You need a loop to iterate the correct number of times and the modulo operator to get each value from the values list:
private static void populateList(int i){
children.clear();
for(int p = 0; p < values.size(); p++){
children.add(values.get(i++%values.size()));
}
}
Or you can fill the children list with the values of the values list. Then just call Collections.rotate (note that indexes in a list are 0 base indexed):
private void populateList(int i){
Collections.rotate(children, -i);
}
Snippet of test:
public class Test {
private final static ArrayList<Integer> values = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8));
private final static ArrayList<Integer> children = new ArrayList<>();
public static void main (String[] args){
populateList(2); //shift the elements in the list
System.out.println(children);
populateListUsingRotate(-2); //get back the original one
System.out.println(children);
}
private static void populateList(int i){
children.clear();
for(int p = 0; p < values.size(); p++){
children.add(values.get(i++%values.size()));
}
}
private static void populateListUsingRotate(int i){
Collections.rotate(children, -i);
}
}
Output:
[3, 4, 5, 6, 7, 8, 1, 2]
[1, 2, 3, 4, 5, 6, 7, 8]
Try This :The List subList(int startIndex, int endIndex)
import java.util.ArrayList;
import java.util.List;
class GetSubListOfJavaArrayList {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("element_1");
arrayList.add("element_2");
arrayList.add("element_3");
arrayList.add("element_4");
arrayList.add("element_5");
List subList = arrayList.subList(1,3);
System.out.println("Elements in sub list :");
for(int i=0; i < subList.size() ; i++)
System.out.println(subList.get(i));
Object obj = subList.remove(0);
System.out.println(obj + " is removed from sub list");
System.out.println("Elements in ArrayList :");
for(int i=0; i < arrayList.size() ; i++)
System.out.println(arrayList.get(i));
}
}
This could be one of many solution :
private void populateList(int i)
{
children.clear();
List<Integer> temp = new ArrayList<Integer>(values.subList(0, i));
for(int j=i; j<values.size(); j++)
children.add(values.get(j));
for(int l=0; l<temp.size(); l++)
children.add(values.get(l));
}
Use subList method of ArrayList
List list1 = values.subList(indexNum, values.size());
List list2 = values.subList(0, indexNum - 1);
children.clear();
children.addAll(list1);
children.addAll(list2);
If your question is:
Adjust list so the first element at position index in a circle.
#Test
public void canShiftTheListToTheSpecifiedIndexCircularly(){
List<Integer> list = Lists.newArrayList();
for(int i = 0; i < 8; i++){
list.add(i + 1);
}
shiftList(3, list);
assertTrue(3 == list.get(0));
assertTrue(2 == list.get(list.size() - 1));
assertTrue(8 == list.get(5));
shiftList(-3, list);
assertTrue(1 == list.get(0));
assertTrue(8 == list.get(7));
}
private List<Integer> shiftList(int posision, List<Integer> list){
//example above seems to use 1 based indexes, hence the oddities with the 1 magic number
// ---
int indexOffset = 1;
boolean isBackwards = posision < 0;
int start = isBackwards ? list.size() + posision : 0;
int end = isBackwards ? list.size() : posision - indexOffset;
List<Integer> tempStorage = Lists.newArrayList();
List<Integer> elmsToShift = list.subList(start, end);
tempStorage.addAll(elmsToShift);
elmsToShift.clear();
if(isBackwards){
list.addAll(0, tempStorage);
}else{
list.addAll(tempStorage);
}
return list;
}

Write a method that merges two array lists, alternating elements from both array lists

Write a method
public static ArrayList merge(ArrayList a, ArrayList b)
that merges two array lists, alternating elements from both array lists. If one array list is shorter than the other, then alternate as long as you can and then append the remaining elemts from the longer array list. For example, if a is
1 4 9 16
and b is
9 7 4 9 11
then merge returns the array list
1 9 4 7 9 4 16 9 11
What I tried doing was writing a for loop with if statements such that a number is added to the merge array list from array list a when i is an even number (i%2==0) and from array list b when i is an odd number. I am however not sure how to deal with the fact that one array list can be longer than the other. Could anyone please help me out?
EDIT: Ok, here is the code (but it is far from correct):
public static ArrayList<Integer> merge(ArrayList<Integer> een, ArrayList<Integer> twee)
{
ArrayList<Integer> merged = new ArrayList<Integer>();
for(int i = 0; i<100; i++)
{
if(i%2!=0)
{
merged.add(a.get(i));
}
if(i%2 == 0)
{
merged.add(b.get(i));
}
}
System.out.println(merged);
return merged;
}
Iterators seem to do the trick most easily
public static <T> ArrayList<T> merge(Collection<T> a, Collection<T> b) {
Iterator<T> itA = a.iterator();
Iterator<T> itB = b.iterator();
ArrayList<T> result = new ArrayList<T>();
while (itA.hasNext() || itB.hasNext()) {
if (itA.hasNext()) result.add(itA.next());
if (itB.hasNext()) result.add(itB.next());
}
return result;
}
Without iterators:
public static <T> ArrayList<T> merge(List<T> a, List<T> b) {
ArrayList<T> result = new ArrayList<T>();
int size = Math.max(a.size(), b.size());
for (int i = 0; i < size; i++) {
if (i < a.size()) result.add(a.get(i));
if (i < b.size()) result.add(b.get(i));
}
return result;
}
Note, I've relaxed the method signature a bit. If you're implementing the merging using iterators, Collection (or even Iterable) will do. Otherwise, List will do. There is no need to require ArrayList as a method argument type
Without Iterator:
public static ArrayList merge(ArrayList a, ArrayList b) {
int c1 = 0, c2 = 0;
ArrayList<Integer> res = new ArrayList<Integer>();
while(c1 < a.size() || c2 < b.size()) {
if(c1 < a.size())
res.add((Integer) a.get(c1++));
if(c2 < b.size())
res.add((Integer) b.get(c2++));
}
return res;
}
Try this:I implemented using Array.
public static void main(String[] args) {
int[] first = { 1, 4, 9, 16 };
int[] second = { 9, 7, 4, 9, 11 };
int[] merge = new int[first.length + second.length];
int j = 0, k = 0, l = 0;
int max = Math.max(first.length, second.length);
for (int i = 0; i < max; i++) {
if (j < first.length)
merge[l++] = first[j++];
if (k < second.length)
merge[l++] = second[k++];
}
System.out.println(Arrays.toString(merge));
}
Output:
[1, 9, 4, 7, 9, 4, 16, 9, 11]
You don't need to check modulo, or you'll skip every second element from each input list.
public static <E> List<E> merge(List<E> een, List<E> twee) {
List<E> merged = new ArrayList<E>(een.size() + twee.size());
List<E> shorter = een.size() <= twee.size() ? een : twee;
List<E> longer = een.size() > twee.size() ? een : twee;
for (int i = 0; i < shorter.size(); i++) {
merged.add(een.get(i));
merged.add(twee.get(i));
}
for (int i = shorter.size(); i < longer.size(); i++) {
merged.add(longer.get(i));
}
return merged;
}
This generic version works for all kind of Lists and generic types.
Here is my solution
LinkedList<Integer> list3 = new LinkedList<Integer>();
Iterator<Integer> itA = list.iterator();
Iterator<Integer> itB = list2.iterator();
while(itA.hasNext() && itB.hasNext()){
list3.add(itA.next());
list3.add(itB.next());
}
I had the same situation and below was my solution:
// array list to hold the merged list
ArrayList<Integer> mergedList = new ArrayList<Integer>();
// Get the bigger size
int maxSize = listOne.size() > listTwo.size() ? listOne.size() : listTwo.size();
// Loop thru the list
for( int i = 0; i <= maxSize; i++){
// We need to check first if index exist then just add it to mergeList
if( i < listOne.size() ) mergedList.add( listOne.get( i ) );
// We need to check first if index exist then just add it to mergeList
if( i < listTwo.size() ) mergedList.add( listTwo.get( i ) );
}
Try this
Iterator iterator1 = arr1.iterator();
Iterator iterator2 = arr2.iterator();
while (iterator1.hasNext() || iterator2.hasNext()) {
if(iterator1.hasNext()){
mergerArr.add(iterator1.next());
}
if(iterator2.hasNext()){
mergerArr.add(iterator2.next());
}
}
Array1= {1,2,3}
Array2= {a,b,c,d,e}
Output= {1, a, 2, b, 3, c, d, e}
public class MergeArray
{
public static void main(String args[])
{
char [] arr1= {'1','2','3'};
char [] arr2= {'a','b','c','d','e'};
int l1= arr1.length;
int l2=arr2.length;
int l3=l1+l2;
char [] arr3=new char[l1+l2];
int i=0;
int j=0;
int k=0;
int m=0;
int r=0;
if(l1<l2)
r=l1;
else
r=l2;
while(m<r)
{
arr3[k++]=arr1[i++];
arr3[k++]=arr2[j++];
m++;
}
while(k<l3)
{
if(l1<l2)
arr3[k++]=arr2[j++];
else
arr3[k++]=arr1[i++];
}
for(int n=0;n<l3;n++)
{
System.out.print(arr3[n]+" ");
}
}
}
I have done this in the following way in php:
<?php
$list1 = array("a","b","c");
$list2 = array(1,2,3);
$list3 = array();
$j=0;
$k=0;
for($i=0;$i<6;$i++)
{
if($i%2==0)
{
$list3[$i]=$list1[$j];
$j++;
}
else
{
$list3[$i]=$list2[$k];
$k++;
}
echo $list3[$i]."<br>";
}
?>
OK, my suggestion is to use ArrayList:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] list1 = in.nextLine().split(",");
String[] list2 = in.nextLine().split(",");
ArrayList<String> merged = new ArrayList<>();
for (int i = 0; i < Math.max(list1.length,list2.length); i++) {
merged.add(list1[i]);
merged.add(list2[i]);
}
System.out.println(String.join(",", merged));
}
You can change the code to Integer if you are sure that the input will be only numbers.

Categories

Resources