Merging two arrays in Java - java

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 elements 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?here is my code so far
package test;
import java.util.Scanner;
public class Arraybig {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int m = scan.nextInt();
int n = scan.nextInt();
int[] A = new int[m];
for (int k = 0; k < m; k++) {
A[k] = scan.nextInt();
}
int[] B = new int[n];
for (int k = 0; k < n; k++) {
B[k] = scan.nextInt();
}
int[] C = new int[m + n];
int max = Math.max(m, n);
int a = 0, b = 0;
for (int i = 0; i < m+n; i++) {
if (i % 2 == 0 && a < A.length) {
C[i] = A[a];
a++;
} else if (i % 2 != 0 && b < B.length) {
C[i] = B[b];
b++;
} else if (a < A.length) {
C[i] = A[a];
a++;
} else {
C[i] = B[b];
b++;
}
}
for (int j = 0; j < C.length; j++) {
System.out.println(C[j] + " ");
}
}
}

A more cleaner approach can be something like this..
list<Integer> a1=//1st list
list<Integer> a2=//2nd list
list<Integer> a3=new Arraylist<Integer>();
int length=(a1.size()<=a2.size())?a1.size():a2.size();
for(int i=0;i<length;i++){
a3.add(a1.get(i));
a3.add(a2.get(i));
}
for(int i=length;i<a1.size();i++){
a3.add(a1.get(i));
}
for(int i=length;i<a2.size();i++){
a3.add(a2.get(i));
}

Hint: How long is the array you want to fill? And how many iterations does your main for loop run? Why is it not the same number?

Related

Program to find pairs in array that XOR to a given value

I am given an array and a value x.
Input example:
2 3
1 2
Where n (length of array) = 2, the value x = 3, and the next line (1, 2) contains the values in the array. I have to find the pairs of indices i, j so that a[i] XOR a[j] = x.
What I have implemented:
import java.util.HashSet;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x = sc.nextInt();
int[] arr = new int[n];
HashSet<Integer> hash = new HashSet<Integer>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
hash.add(arr[i]);
}
int count = 0;
for (int i = 0; i < n; i++) {
if (hash.contains(arr[i]^x)) {
count++;
}
}
System.out.println(count/2);
}
}
I have the divided the result by two because we only want to count a given pair once (only count [1, 2] not [1, 2] and [2, 1]).
I pass the given test above where the output is 1, and this supplementary one where the output is 2.
6 1
5 1 2 3 4 1
However I seem to fail some extra ones which I cannot see.
The problem is that you check "contains", but for duplicate values this only returns a single occurrence. By using a set you throw duplicates away. Instead you should have a HashMap with number of occurrences:
Map<Integer, Integer> hash = new HashMap<>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
if (!hash.containsKey(arr[i])) {
hash.put(arr[i], 0)
}
hash.put(arr[i], hash.get(arr[i]) + 1);
}
int count = 0;
for (int i = 0; i < n; i++) {
if (hash.containsKey(arr[i]^x)) {
count += hash.get(arr[i]^x);
}
}
Your logic of dividing the count by 2 as the final answer, is not correct.
Replace your logic by the following:
HashSet<Integer> hash = new HashSet<Integer>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int count = 0;
for (int i = 0; i < n; i++) {
if (hash.contains(arr[i]^x)) {
count++;
}
hash.add(arr[i]);
}
System.out.println(count);
Your program doesn't handle duplicate numbers properly. It deals with 5 1 2 3 4 1 okay because 1 isn't part of the solution. What if it is?
Let's say number a[i] ^ a[j] is a solution as is a[i] ^ a[k]. In other words, a[j] == a[k]. The line hash.contains(arr[i]^x) will only count a[i] once.
You can solve this by having nested for loops.
for (int i = ...) {
for (int j = ...) {
if (a[i] ^ a[j] == x) {
count++;
}
}
}
This approach lets you get rid of the hash set. And if you're clever enough filling out the ... parts you can avoid double counting the pairs and won't have to divide count by 2.

What is the procedure for Minimum contiguous sum with atmost K swaps

I have an array say {-1,2,3,4,-3,-2,1,5}
Now I would like to find the minimum contiguous sum subarray for the given array with atmost K swaps.
In the array above the minimum contiguous sum is -5 and subarray is {-3,-2}
Say for K=1 How should I swap the elements
Should I swap the left element of the sub array i,e; swaping element 4 at a[3] which is left to it with -1 (again with which number (sub question pops up in my mind)?
a. whether the lowest of the the remaining elements (with any sorting technique of the remaining elements excluding subarrays). If I do this I will swap -1 with 4 and the min sum will be {-1,-3,-2}
As per "atmost" K swaps I can return this the subarray with only one swap even how long the array is
Should I swap the element 1 at the postion a[6] with -1 and get the sub array with min sum as {-3,-2,-1}. Again following the same question at point a above.
This whole process I would like to do with recursion. As I am dealing with arrays with N integers. Which is best approach I should follow recursion or iteration?
import java.io.;
import java.util.;
class TestClass {
static Scanner scanner;
public static void main(String args[] ) throws Exception {
scanner=new Scanner(System.in);
int t=scanner.nextInt();
while(t>0){
t--;
int n=scanner.nextInt();
int k=scanner.nextInt();
int[] array=new int[n];
for(int i=0;i<array.length;i++)
{
array[i]=scanner.nextInt();
}
int ans=findingMinimumSumSubarray(array,k);
System.out.println(ans);
}
}
public static int findingMinimumSumSubarray(int[] values, int k) {
int len = values.length;
int res = values[0];
for (int l = 0; l < len; l++) {
for (int r = l; r < len; r++) {
List<Integer> A= new ArrayList<Integer>();
List<Integer> B = new ArrayList<Integer>();
int abc = 0;
for (int i = 0; i < len; i++) {
if (i >= l && i <= r) {
A.add(values[i]);
abc += values[i];
} else {
B.add(values[i]);
}
}
Collections.sort(A);
Collections.sort(B);
Collections.reverse(B);
res = Math.min(res, abc);
for (int t = 1; t <= k; t++) {
if (t > A.size() || t > B.size()) break;
abc -= A.get(A.size() - t);
abc += B.get(B.size() - t);
res = Math.min(res, abc);
}
}
}
return res;
}
}

Array method that returns a new array where every number is replicated by “itself” # of times

I am trying to write a method in Java that receives an array and returns a new array where each number is printed that number of times. Here is an example input and output: "1 2 3 0 4 3" ---> "1 2 2 3 3 3 4 4 4 4 3 3 3". I am stuck and my program will not compile. Does anyone see where I am going wrong?
public static int [] multiplicity(int [] nums) {
for (int i = 0 ; i < nums.length ; i++) {
int size = nums.length + 1;
int newNums[] = new int [size];
for (int j = 0 ; j < nums.length ; j++) {
int value = nums[j];
for (int v = 0 ; v < value ; v++) {
newNums[j + v] = value;
}
}
}
return newNums;
}
Your current code does not size your new array correctly, you could fix your compiler errors easily enough like
int size=nums.length+1;
int newNums [] = new int [size];
for (int i=0; i<nums.length; i++)
{
// int size=nums.length+1;
// int newNums [] = new int [size];
But that clearly won't allow you to populate all of your values. Instead (assuming you can't use a dynamic data-type like a Collection), you'll need to iterate the array once to get the final count of elements and then populate your array. Something like,
public static int[] multiplicity(int[] nums) {
// first pass
int count = 0;
for (int num : nums) {
for (int i = 0; i < num; i++) {
count++;
}
}
int[] ret = new int[count];
count = 0;
// second pass
for (int num : nums) {
for (int i = 0; i < num; i++) {
ret[count++] = num;
}
}
return ret;
}
Then you could test it like,
public static void main(String arg[]) {
int[] in = { 1, 2, 3, 0, 4, 3 };
int[] out = multiplicity(in);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < out.length; i++) {
if (i != 0) {
sb.append(' ');
}
sb.append(out[i]);
}
String expected = "1 2 2 3 3 3 4 4 4 4 3 3 3";
System.out.println(expected.equals(sb.toString()));
}
Output is
true
Once you initialise your int[] newNums, you can't dynamically resize it. Initialising it again will discard the previous array.
Here's another way to solve the problem:
public static int [] multiplicity (int [ ] nums)
{
// create a list to contain the output
List<Integer> newNums = new ArrayList<Integer>();
// for each incoming int
if(nums != null) {
for (final int i : nums)
{
// repeat adding the value
for(int j = 0; j < i; j++) {
newNums.add(i);
}
}
}
// now copy from the List<Integer> to the result int[]
int[] result = new int[newNums.size()];
for(int i=0; i < newNums.size(); i++) {
result[i] = newNums.get(i);
}
// return the result
return result;
}
You can't know the new array size until you explore the whole input array.
So you can
Explore the whole array and compute the lengh, then, re-explore the input array and fill the new. You need only 1 memory allocation (only 1 new int[])
Create a vector and fill it. Then use the .toarray method
Exemple to fill the array (check he had the right size)
int k = 0
for(int i: nums) {
for(int j = 0; j < i; j++) {
newArray[k] = i;
k++;
}
}

How can i find the positions to the three lowest integers in an array?

I how can I find the positions of the three lowest integers in an array?
I've tried to reverse it, but when I add a third number, it all goes to hell :p
Does anybody manage to pull this one off and help me? :)
EDIT: It would be nice to do it without changing or sorting the original array a.
public static int[] lowerThree(int[] a) {
int n = a.length;
if (n < 2) throw
new java.util.NoSuchElementException("a.length(" + n + ") < 2!");
int m = 0; // position for biggest
int nm = 1; // position for second biggest
if (a[1] > a[0]) { m = 1; nm = 0; }
int biggest = a[m]; // biggest value
int secondbiggest = a[nm]; // second biggest
for (int i = 2; i < n; i++) {
if (a[i] > secondbiggest) {
if (a[i] > biggest) {
nm = m;
secondbiggest = biggest;
m = i;
biggest = a[m];
}
else {
nm = i;
secondbiggest = a[nm];
}
}
} // for
return new int[] {m,nm};
}
EDIT: I've tried something here but it still doesn't work. I get wrong output + duplicates...
public static int[] lowerthree(int[] a) {
int n= a.length;
if(n < 3)
throw new IllegalArgumentException("wrong");
int m = 0;
int nm = 1;
int nnm= 2;
int smallest = a[m]; //
int secondsmallest = a[nm]; /
int thirdsmallest= a[nnm];
for(int i= 0; i< lengde; i++) {
if(a[i]< smallest) {
if(smalles< secondsmallest) {
if(secondsmallest< thirdsmallest) {
nnm= nm;
thirdsmallest= secondsmallest;
}
nm= m;
secondsmallest= smallest;
}
m= i;
smallest= a[m];
}
else if(a[i] < secondsmallest) {
if(secondsmallest< thirdsmallest) {
nnm= nm;
thirdsmallest= secondsmallest;
}
nm= i;
secondsmallest= a[nm];
}
else if(a[i]< thirdsmallest) {
nnm= i;
thirdsmallest= a[nnm];
}
}
return new int[] {m, nm, nnm};
}
Getting the top or bottom k is usually done with a partial sort. There are versions that change the original array and those that dont.
If you only want the bottom (exactly) 3 and want to get their positions, not the values, your solution might be the best fit. This is how I would change it to support the bottom three. (I have not tried to compile and run, there may be little mistakes but the genereal idea should fit)
public static int[] lowerThree(int[] a) {
if (a.length < 3) throw
new java.util.NoSuchElementException("...");
int indexSmallest = 0;
int index2ndSmallest = 0;
int index3rdSmallest = 0;
int smallest = Integer.MAX_VALUE;
int sndSmallest = Integer.MAX_VALUE;
int trdSmallest = Integer.MAX_VALUE;
for (size_t i = 0; i < a.length; ++i) {
if (a[i] < trdSmallest) {
if (a[i] < sndSmallest) {
if (a[i] < smallest) {
trdSmallest = sndSmallest;
index3rdSmallest = index2ndSmallest;
sndSmallest = smallest;
index2ndSmallest = indexSmallest;
smallest = a[i];
indexSmallest = i;
continue;
}
trdSmallest = sndSmallest;
index3rdSmallest = index2ndSmallest;
sndSmallest = a[i];
index2ndSmallest = i;
continue;
}
trdSmallest = a[i];
index3rdSmallest = i;
}
}
return new int[] {indexSmallest, index2ndSmallest, index3rdSmallest};
}
This will have the three lowest numbers, need to add some test cases..but here is the idea
int[] arr = new int[3];
arr[0] = list.get(0);
if(list.get(1) <= arr[0]){
int temp = arr[0];
arr[0] = list.get(1);
arr[1] = temp;
}
else{
arr[1] = list.get(1);
}
if(list.get(2) < arr[1]){
if(list.get(2) < arr[0]){
arr[2] = arr[1];
arr[1] = arr[0];
arr[0] = list.get(2);
}
else{
arr[2] = arr[1];
arr[1] = list.get(2);
}
}else{
arr[2] = list.get(2);
}
for(int integer = 3 ; integer < list.size() ; integer++){
if(list.get(integer) < arr[0]){
int temp = arr[0];
arr[0] = list.get(integer);
arr[2] = arr[1];
arr[1] = temp;
}
else if(list.get(integer) < arr[1]){
int temp = arr[1];
arr[1] = list.get(integer);
arr[2] = temp;
}
else if(list.get(integer) <= arr[2]){
arr[2] = list.get(integer);
}
}
I'd store the lowest elements in a LinkedList, so it is not fixed on the lowest 3 elements. What do you think?
public static int[] lowest(int[] arr, int n) {
LinkedList<Integer> res = new LinkedList();
for(int i = 0; i < arr.length; i++) {
boolean added = false;
//iterate over all elements in the which are of interest (n first)
for(int j = 0; !added && j < n && j < res.size(); j++) {
if(arr[i] < res.get(j)) {
res.add(j, i); //the element is less than the element currently considered
//one of the lowest n, so insert it
added = true; //help me get out of the loop
}
}
//Still room in the list, so let's append it
if(!added && res.size() < n) {
res.add(i);
}
}
//copy first n indices to result array
int[] r = new int[n];
for(int i = 0; i < n && i < res.size(); i++) {
r[i] = res.get(i);
}
return r;
}
In simple words, you need to compare every new element with the maximum of the three you have at hand, and swap them if needed (and if you swap, max of the three has to be recalculated).
I would use 2 arrays of size 3 each:
arrValues = [aV1 aV2 aV3] (reals)
arrPointers = [aP1 aP2 aP3] (integers)
and a 64 bit integer type, call it maxPointer.
I will outline the algorithm logic, since I am not familiar with Java:
Set arrValues = array[0] array[1] array[2] (three first elements of your array)
Set arrPointers = [0 1 2] (or [1 2 3] if your array starts from 1)
Iterate over the remaining elements. In each loop:
Compare the Element scanned in this iteration with arrValues[maxPointer]
If Element <= arrValues[maxPointer],
remove the maxPointer element,
find the new max element and reset the maxPointer
Else
scan next element
End If
Loop
At termination, arrPointers should have the positions of the three smallest elements.
I hope this helps?
There is an easy way to find the positions of three lowest number in an Array
Example :
int[] arr={3,5,1,2,9,7};
int[] position=new int[arr.length];
for(int i=0;i<arr.length;i++)
{
position[i]=i;
}
for(int i=0;i<arr.length;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
int tem=position[i];
position[i]=position[j];
position[j]=tem;
}
}
}
System.out.println("Lowest numbers in ascending order");
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
System.out.println("And their previous positions ");
for(int i=0;i<arr.length;i++)
{
System.out.println(position[i]);
}
Output
you can do it in 3 iterations.
You need two extra memory, one for location and one for value.
First iteration, you will keep the smallest value in one extra memory and its location in the second. As you are iterating, you compare every value in the slot with the value slot you keep in the memory, if the item you are visiting is smaller than what you have in your extra value slot, you replace the value as well as the location.
At the end of your first iteration, you will find the smallest element and its corresponding location.
You do the same for second and third smallest.

Completely stumped on a multiple loop Java program

The following is NOT a homework problem, it's just a set of problems that I've been working through for practice and I was wondering if anybody else could figure it out:
http://codingbat.com/prob/p159339
Return an array that contains exactly the same numbers as the given array, but rearranged so that every 3 is immediately followed by a 4. Do not move the 3's, but every other number may move. The array contains the same number of 3's and 4's, every 3 has a number after it that is not a 3 or 4, and a 3 appears in the array before any 4.
*SOLVED - here is my working code:
public int[] fix34(int...nums)
{
int[] returnArray = new int[nums.length];
//ASSIGN ARRAY
//We know that all 3's can't be moved, and after every 3 there
//will automatically be a 4
for(int i = 0; i<nums.length; i++)
{
if(nums[i] == 3)
{
returnArray[i] = 3;
returnArray[i+1] = 4;
}
}
//REBUILD ARRAY - UNMOVED INDEXES
//If a value was not moved/affected by the above, it will get placed into the array
//in the same position
for (int i = 0; i < nums.length; i++)
{
if (returnArray[i] != 3 && returnArray[i] != 4 && nums[i] != 3 && nums[i] != 4)
{
returnArray[i] = nums[i];
}
}
//REBUILD ARRAY - MOVED INDEXES
//changed values = 0 in returnArray, as a result, any time we hit a 0 we
//can simply assign the value that was in the 4's place in the nums array
OuterLoop: for (int i = 0; i < nums.length; i++)
{
if (returnArray[i] == 0)
{
for (int n = 0; n < returnArray.length; n++)
{
if (returnArray[n] == 4)
{
returnArray[i] = nums[n];
continue OuterLoop;
}
}
}
}
return returnArray;
}
I don't know java, but maybe I can help anyway. i dont want to give you the solution, but think of it like this:
you can move every number that isn't a 3. that's our only limit. that being said:
the only spots you need to change are the spots following 3s....so....every time you loop through, your program should be aware if it finds a spot after a 3 that isn't a 4....
it should also be aware if it finds any 4s not preceded by a 3......
during each loop, once it's found the location of each of those two things, you should know what to do.
Initialize all the variables
for(int i = 0; i<n-1; i++)
{
if(arr[i] == 3)
{
if(arr[i+1] == 4)
continue;
else
{
temp = 0;
while(arr[temp] != 4)
temp++;
//Write your own code here
}
//Complete the code
}
I have NOT provided the entire code. Try completing it as you said it was for your practice.
public int[] fix34(int[] nums) {
int[] arr = new int[nums.length];
int index = 0;
int tempVal= 0,j=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==3){
arr[i] = nums[i];
index=i+1;
tempVal = nums[i+1];
j=index;
while(j<nums.length){
if(j<nums.length && nums[j]==4){
//System.out.println(j+"\t="+nums[j]);
nums[j]=tempVal;
nums[index] = 4;
break;
}
j++;
}
tempVal=0;
index=0;
}else{
arr[i] = nums[i];
}
}
index =0;
for(int i=0;i<nums.length;i++){
if(nums[i]==3 && nums[i+1]==4){
i+=1;
}else if(nums[i]==4){
index = i;
j=index;
while(j<nums.length){
if(nums[j]==3 && nums[j+1]!=4){
arr[index] = nums[j+1];
arr[j+1] = 4;
}
j++;
}
}
}
return arr;
}
Here's mine: A little overkill, but is always right, anyways i make 2 additional arrays and I make 2 passes in the loop putting the correct elements in the correct places. See Logic Below.
public int[] fix34(int[] nums) {
int index1 = 0;
int index2 = 0;
int index3 = 0;
int[] only4 = fours(nums); //holds all 4's in nums
int[] misc = new int[count4(nums)]; //will hold numbers after 3
for(int a = 0; a < nums.length - 1; a++){
if(nums[a] == 3){
misc[index1] = nums[a + 1]; //get it for later use
index1++;
nums[a + 1] = only4[index2]; //now the number after 3 is a 4, from the
index2++; //only4 array
}
}
for(int b = 1; b < nums.length; b++){
if(nums[b] == 4 && nums[b - 1] != 3){ //finds misplaced 4's
nums[b] = misc[index3]; //replaces lone 4's with the
index3++; //right hand side of each 3 original values.
}
}
return nums;
}
public int count4(int[] nums){
int cnt = 0;
for(int e : nums){
if(e == 4){
cnt++;
}
}
return cnt;
}
public int[] fours(int[] nums){
int index = 0;
int[] onlyFours = new int[count4(nums)]; //must set length
for(int e : nums){
if(e == 4){
onlyFours[index] = e;
index++;
}
}
return onlyFours;
}
I solved mine using two ArrayLists which contain the places of 3's and 4's.
I hope this helps.
public int[] fix34(int[] nums)
{
//Create a copy of nums to manipulate.
int[] ret = nums;
//Create two ArrayLists which carry corresponding places of 3 and 4;
ArrayList<Integer> threePositions = new ArrayList<Integer>();
ArrayList<Integer> fourPositions = new ArrayList<Integer>();
//Get the places of 3 and 4 and put them in the respective ArrayLists.
for (int i = 0; i < ret.length; i++)
{
if (ret[i] == 3)
{
threePositions.add(i);
}
if (ret[i] == 4)
{
fourPositions.add(i);
}
}
//Swap all ints right after the 3 with one of the 4s by using the referenced
//ArrayLists values.
for (int i = 0; i < threePositions.size(); i++)
{
int temp = ret[threePositions.get(i) + 1];
ret[threePositions.get(i) + 1] = ret[fourPositions.get(i)];
ret[fourPositions.get(i)] = temp;
}
//Return the ret array.
return ret;
}

Categories