Convert List of Lists to int array - java

I have input of list of lists which i want to convert into int array which can help for my logic
list of Lists "lst" has input [[1,0,1],[1,1,0],[0,0,1]]
output array should be like {{1,0,1},{1,1,0},{0,0,1}}
int[] arr = new int[lst.size()];
for(int i=0;i<lst.size();i++){
for(int j=0;j<lst.size();j++){
arr[i] = lst.get(i).get(j);
}
}

Here are two ways.
The data
List<List<Integer>> list = List.of(List.of(1,0,1),
List.of(1,1,0),
List.of(0,0,1));
allocate an Array of arrays for the number of rows.
iterate over the rows of the data.
create an array to hold the inner array contents
fill it and assign to the array of arrays.
int[][] arr = new int[list.size()][];
for (int i = 0; i < list.size(); i++) {
List<Integer> lst = list.get(i);
int [] temp = new int[lst.size()];
for (int k = 0; k < lst.size(); k++) {
temp[k] = lst.get(k);
}
arr[i] = temp;
}
System.out.println(Arrays.deepToString(arr));
Or
stream the lists of lists
then stream each of those lists, mapping to an int and creating an array.
the put those arrays in an Array of arrays.
int[][] arr = list.stream()
.map(ls->ls.stream().mapToInt(a->a).toArray())
.toArray(int[][]::new);
System.out.println(Arrays.deepToString(arr));
Both print
[[1, 0, 1], [1, 1, 0], [0, 0, 1]]

Related

How to add 1 to each value in an array (in Java)?

Here's the prompt:
Loop through an integer array adding one to each element. Return the resulting array. The array may be of any length including 0.
Here's what I have so far:
public int[] add1toEach(int[] nums) {
int[] array = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
nums[i]++;
}
return array;
}
It works with add1toEach[] and add1toEach[-1] but that's it. How do I get it to spit out [7, 7, 3] if add1toEach[6, 6, 2] is the input?
The fact is that you aren't assigning the new added result to the array, nor are you adding it properly.
The proper code is:
public static int[] add1toEach(int[] nums) {
int[] array = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
array[i]=nums[i]+1;
}
return array;
}
What's happening here is that we add 1 to the item, then we assign the item to an identical array, but which the items are all empty. This happens to every single item of the array, as demonstrated in the statement in the for loop i < nums.length; i++.
This working example:
public class MyClass {
public static void main(String args[]) {
int[] nums = {1, 2, 3};
int[] newnums = add1toEach(nums);
for(int i = 0; i < newnums.length; i++){
System.out.println(newnums[i]);
}
}
public static int[] add1toEach(int[] nums) {
int[] array = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
array[i]=nums[i]+1;
}
return array;
}
}
Produces
2
3
4
What you're code doing is it only returns the untouched int[] array.
Since you have set the length of your array, you just need to set values to your array with position array[i] to make the values assigned and intact position.
array[i]=nums[i]++;

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.

Java sort second array depending on indexes of first array

I have two int arrays
int[] sum=new int[n];
int[] newTime=new int[n];
First: 1 5 3
Second 10 15 13
Arrays.sort(sum);
Prints 1 3 5
What I want is even for the second array to be sorted with the same indexes
of the
first=>second : 10 13 15
I have tried with maps:
SortedMap<Integer, Integer> m = new TreeMap<Integer, Integer>();
for(int i = 0; i < priorities.length; i++){
m.put(sum[i],newTime[i]);
}
It just sorts the first array only,the indexes of the second array don't change.Help is appreciated!
Thank You!
You could do it with java-8 like this for example:
int[] left = new int[] { 1, 5, 3 };
int[] right = new int[] { 10, 15, 13 };
IntStream.range(0, left.length)
.boxed()
.map(x -> new AbstractMap.SimpleEntry<>(left[x], right[x]))
.sorted(Comparator.comparing(SimpleEntry::getKey))
.forEach(System.out::println);
EDIT
to actually get the second array:
Integer[] second = IntStream.range(0, left.length)
.boxed()
.map(x -> new AbstractMap.SimpleEntry<>(left[x], right[x]))
.sorted(Comparator.comparing(SimpleEntry::getKey))
.map(SimpleEntry::getValue)
.toArray(Integer[]::new);
Your TreeMap approach leads to what you need:
SortedMap<Integer, Integer> m = new TreeMap<Integer, Integer>();
for(int i = 0; i < priorities.length; i++){
m.put(sum[i],newTime[i]);
}
// this will print the elements of the second array in the required order
for (Integer i : m.values()) {
System.out.println (i);
}
Of course you can assign the elements back to the original array if you want:
int count = 0;
for (Integer i : m.values()) {
newTime[count] = i;
}
As correctly commented by mlecz, this solution will only work if the first array (sum) has no duplicates.
Here is the solution, which works when there are duplicates in first array.
You keep values from both arrays together, sort them using indices from one array, and make a list, from corresponding indices from second array.
static Integer[] sort(int[] arr1, int[] arr2) {
assert arr1.length == arr2.length;
class Tuple{
int a1;
int a2;
}
List<Tuple> tuples = new ArrayList<>();
for(int i=0;i<arr1.length;i++){
Tuple t = new Tuple();
t.a1=arr1[i];
t.a2=arr2[i];
tuples.add(t);
}
tuples.sort((t1,t2)->Integer.compare(t1.a1,t2.a1));
return (Integer[]) tuples.stream().map(t->t.a2).collect(Collectors.toList()).toArray(new Integer[arr1.length]);
}
You may sort both arrays at the same time, following the reordering of the first array like this :
int[] sum = { 1, 5, 3 };
int[] newTime = { 10, 15, 13 };
for (int i = 0; i < sum.length; i++) {
for (int j = 0; j < sum.length; j++) {
if (sum[i] < sum[j]) {
int temp = sum[i];
int temp2 = newTime[i];
sum[i] = sum[j];
sum[j] = temp;
newTime[i] = newTime[j];
newTime[j] = temp2;
}
}
}
System.out.println(Arrays.toString(sum));
System.out.println(Arrays.toString(newTime));

Flatten 2d or 3d Array in Java

I need to take a multidimensional array and flatten it so that if the array looks like:
[1,2,3]
[4,5,6]
Then it is transformed to:
[1,2,3,4,5,6]
I also need to accommodate 3D arrays and flatten them also.
Here is what I've got so far...
class ArrayOperations {
private int[] postFlattenedArray;
public ArrayOperations {
flattenedArray = new int[arrayDimensions[0]];
// arrayDimesnsions of 3,4 is a a 3x4 array; 3,4,5 is a 3x4x5 array
//set up ints to hold total size and dimensionality of array
int prod = 1
int dimensions = 0;
newArray = new int[prod - 1];
for (int i: arrayDimensions) {
prod = prod * i;
dimensions += 1;
}
int k = 0;
for ( int i: arrayDimensions ){
for ( int j = 0; j <= i; j++ ){
newArray[k++] = flattenedArray[j][0][0]
}
}
}
I know I need to run some nested for loops, but I'm having difficulty grasping how I would do this for different array dimensions. So if the array has dimensions; 3,5,6 then I am not sure how to run a loop so that it iterates like:
[1..4][0][0], [0][1..5][0], [0][0][1..6]
It seems to that the simplest solution is implementing a recursive function flatten (which will probably have to be generic to be able to handle arrays of anything), which will return the array itself if already flat or recursively call itself on all the internal arrays and concatenate the results.
Try this.
static void flatten(Object object, List<Integer> list) {
if (object.getClass().isArray())
for (int i = 0; i < Array.getLength(object); ++i)
flatten(Array.get(object, i), list);
else
list.add((int)object);
}
static int[] flatten(Object object) {
List<Integer> list = new ArrayList<>();
flatten(object, list);
int size = list.size();
int[] result = new int[size];
for (int i = 0; i < size; ++i)
result[i] = list.get(i);
return result;
}
and
int[][][] array = {
{{1, 2, 3}, {4, 5}},
{{6}, {7, 8, 9}},
};
System.out.println(Arrays.toString(flatten(array)));
// -> [1, 2, 3, 4, 5, 6, 7, 8, 9]

How to shift array elements after removing one?

I need to add a shift function only with loops (it means I can't use any ListArray method et simila, so this is not a copy of any other question with those methods.) to this method which removes a specific integer from a given array, and put the outcome into another array, and then returning it.
public static int[] removeInt(int v, int[] in) {
int length = 0;
length = in.length;
int[] toReturn = new int[length];
for (int b = 0; b < length; b++) {
toReturn[b] = 0;
}
for (int i = 0; i < length; i++) {
if (in[i] != v) {
toReturn[i] = in[i];
}
}
return toReturn;
}
If the input for the array is {1, 2, 3, 4, 5}, and the number to remove is {2}, the output will be {1 0 3 4 5}, but it needs to be {1 3 4 5}, and I can't find a way to shift numbers to the left.
'v' comes from the main, user input. Same for 'in', fullfilled before by the user.
You will have to iterate over the array two times: The first time, you count how often v is contained in in. If count is 0, you can return in, otherwise you would have to create a new array of length in.length - count. Then again you have to iterate over in and add every value that is not v to your Array.
int count = 0;
for(int i: in) {
if (i==v) {
count++;
}
}
int[] result = new int[in.length-count];
int pos=0;
for(int i: in) {
if (i!=v) {
result[pos] = i;
pos++;
}
}
But you could use Collections to make it easier:
public static void main(String[] args) {
int v = 2;
int[] in = new int[]{1, 2, 3, 4, 5};
List<Integer> list = new ArrayList<>();
for(int i: in) {
if (i!=v) {
list.add(i);
}
}
Integer[] result = list.toArray(new Integer[]{});
}
The disadvantage of this, however, would be that you have an Array of Integer and not of int.
Have you considered using a LinkedList? This internally manages the array so you don't need to deal with moving the elements yourself; you can just call remove().

Categories

Resources