merge two arrays in ascending order - arrays

i wanted to put two sorted arrays into one array in ascending order, but i don't what i did wrong.
it won't put them in order, just combine the two arrays together.
int [] merged = new int[count1 + count2];
int merg1 = 0, merg2 = 0, index = 0;
while (merg1 < count1 && merg2 < count2) {
if (ary1[merg1] <= ary2[merg2]) {
merged[index++] = ary1[merg1++];
}
else {
merged[index++] = ary2[merg2++];
}
while (merg1 < count1) {
merged[index++] = ary1[merg1++];
}
while (merg2 < count2) {
merged[index++] = ary2[merg2++];
}
for (int i = 0; i < index; i++) {
System.out.print(merged[i] + " ");
}

What are the last two while loops for? You may not need them. It seems that you sort the first two numbers then the while loops copy the first array then the second without sorting them.

Can you share how the results look for the following?
arry1 = [1,2,6,7]
arry2 = [2,3,4,8]
I agree with Paradox, without the two additional while loops, your logic above should be enough. ex:
while (merg1 < count1 && merg2 < count2) {
if (ary1[merg1] <= ary2[merg2]) {
merged[index++] = ary1[merg1++];
}
else {
merged[index++] = ary2[merg2++];
}
}

Wouldn't the error come from the
while (merg1 < count1 && merg2 < count2) {
...
}
It terminates when one of the numbers goes past its limit. After the while loop, I would add another loop that adds the rest of the remaining array to the merged array.

can you just use the Array utilities? For example:
int[] array1 = {1,2,6,7};
int[] array2 = {2,3,4,8};
int[] mergedarray = new int[array1.length + array2.length];
System.arraycopy(array1, 0, mergedarray, 0, array1.length);
System.arraycopy(array2, 0, mergedarray, array1.length, array2.length);
Arrays.sort(mergedarray);
That should give you the results your are looking for.

Related

Google App Script breaking singular element into 1D array with several elements

I've created a custom script in GAS (for Google Sheets) so I could join several data sources into one unique display. I added a .splice in the middle so I could cut out all null elements inside the arrays (which meant removing blank rows in the return array).
Here is it how the code goes:
function COMPILER(){
var i;
var c;
var r;
var display = [];
for (i = 0; i < arguments.length; i++) {
for (c = 0; c < arguments[i].length;c++) {
display.push(arguments[i][c]);
};};
for (r = display.length-1; r >= 0; r--) {
if (display[r][1]==""){
display.splice(r, 1)
};};
return display
};
The code works fine with 2+D arrays and with 1D arrays that have 2+ elements; but when its working with 1D arrays that have only one element, it unintendedly breaks down the strings into several elements.
Instead of returning:
ar1
ar2
It returns
a
r
1
a
r
2
How could I solve this?
I think/assume this is what you're trying to do:
function COMPILER()
{
var display = [];
for(var i = 0, numArguments = arguments.length; i < numArguments; ++i)
{
//console.log([i, arguments[i], Array.isArray(arguments[i])]);
if(Array.isArray(arguments[i]))
{
for(var j = 0, len = arguments[i].length; j < len; ++j)
{
if(arguments[i][j] != "")
{
display.push(arguments[i][j]);
}
}
}
else if(arguments[i] != "")
{
display.push(arguments[i]);
}
}
return display;
}
I can't confirm/test cause I don't know how you're calling COMPILER.

The longest sub-array with switching elements

An array is called "switching" if the odd and even elements are equal.
Example:
[2,4,2,4] is a switching array because the members in even positions (indexes 0 and 2) and odd positions (indexes 1 and 3) are equal.
If A = [3,7,3,7, 2, 1, 2], the switching sub-arrays are:
== > [3,7,3,7] and [2,1,2]
Therefore, the longest switching sub-array is [3,7,3,7] with length = 4.
As another example if A = [1,5,6,0,1,0], the the only switching sub-array is [0,1,0].
Another example: A= [7,-5,-5,-5,7,-1,7], the switching sub-arrays are [7,-1,7] and [-5,-5,-5].
Question:
Write a function that receives an array and find its longest switching sub-array.
I would like to know how you solve this problem and which strategies you use to solve this with a good time complexity?
I am assuming that the array is zero indexed .
if arr.size <= 2
return arr.size
else
ans = 2
temp_ans = 2 // We will update ans when temp_ans > ans;
for i = 2; i < arr.size ; ++i
if arr[i] = arr[i-2]
temp_ans = temp_ans + 1;
else
temp_ans = 2;
ans = max(temp_ans , ans);
return ans;
I think this should work and I don't think it needs any kind of explanation .
Example Code
private static int solve(int[] arr){
if(arr.length == 1) return 1;
int even = arr[0],odd = arr[1];
int start = 0,max_len = 0;
for(int i=2;i<arr.length;++i){
if(i%2 == 0 && arr[i] != even || i%2 == 1 && arr[i] != odd){
max_len = Math.max(max_len,i - start);
start = i-1;
if(i%2 == 0){
even = arr[i];
odd = arr[i-1];
}else{
even = arr[i-1];
odd = arr[i];
}
}
}
return Math.max(max_len,arr.length - start);
}
It's like a sliding window problem.
We keep track of even and odd equality with 2 variables, even and odd.
Whenever we come across a unmet condition, like index even but not equal with even variable and same goes for odd, we first
Record the length till now in max_len.
Reset start to i-1 as this is need incase of all elements equal.
Reset even and odd according to current index i to arr[i] and arr[i-1] respectively.
Demo: https://ideone.com/iUQti7
I didn't analyse the time complexity, just wrote a solution that uses recursion and it works (I think):
public class Main
{
public static int switching(int[] arr, int index, int end)
{
try
{
if (arr[index] == arr[index+2])
{
end = index+2;
return switching(arr, index+1, end);
}
} catch (Exception e) {}
return end;
}
public static void main(String[] args)
{
//int[] arr = {3,2,3,2,3};
//int[] arr = {3,2,3};
//int[] arr = {4,4,4};
int[] arr = {1,2,3,4,5,4,4,7,9,8,10};
int best = -1;
for (int i = 0; i < arr.length; i++)
best = Math.max(best, (switching(arr, i, 0) - i));
System.out.println(best+1); // It returns, in this example, 3
}
}
int switchingSubarray(vector<int> &arr, int n) {
if(n==1||n==2) return n;
int i=0;
int ans=2;
int j=2;
while(j<n)
{
if(arr[j]==arr[j-2]) j++;
else
{
ans=max(ans,j-i);
i=j-1;
j++;
}
}
ans=max(ans,j-i);
return ans;
}
Just using sliding window technique to solve this problems as element at j and j-2 need to be same.
Try to dry run on paper u will surely get it .
# Switching if numbers in even positions equal to odd positions find length of longest switch in continuos sub array
def check(t):
even = []
odd = []
i = 0
while i < len(t):
if i % 2 == 0:
even.append(t[i])
else:
odd.append(t[i])
i += 1
if len(set(even)) == 1 and len(set(odd)) == 1:
return True
else:
return False
def solution(A):
maxval = 0
if len(A) == 1:
return 1
for i in range(0, len(A)):
for j in range(0, len(A)):
if check(A[i:j+1]) == True:
val = len(A[i:j+1])
print(A[i:j+1])
if val > maxval:
maxval = val
return maxval
A = [3,2,3,2,3]
A = [7,4,-2,4,-2,-9]
A=[4]
A = [7,-5,-5,-5,7,-1,7]
print(solution(A))

Transform an array to another array by shifting value to adjacent element

I am given 2 arrays, Input and Output Array. The goal is to transform the input array to output array by performing shifting of 1 value in a given step to its adjacent element. Eg: Input array is [0,0,8,0,0] and Output array is [2,0,4,0,2]. Here 1st step would be [0,1,7,0,0] and 2nd step would be [0,1,6,1,0] and so on.
What can be the algorithm to do this efficiently? I was thinking of performing BFS but then we have to do BFS from each element and this can be exponential. Can anyone suggest solution for this problem?
I think you can do this simply by scanning in each direction tracking the cumulative value (in that direction) in the current array and the desired output array and pushing values along ahead of you as necessary:
scan from the left looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the right
scan from the right looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the left
For your example the steps would be:
FWD:
[0,0,8,0,0]
[0,0,7,1,0]
[0,0,6,2,0]
[0,0,6,1,1]
[0,0,6,0,2]
REV:
[0,1,5,0,2]
[0,2,4,0,2]
[1,1,4,0,2]
[2,0,4,0,2]
i think BFS could actually work.
notice that n*O(n+m) = O(n^2+nm) and therefore not exponential.
also you could use: Floyd-Warshall algorithm and Johnson’s algorithm, with a weight of 1 for a "flat" graph, or even connect the vertices in a new way by their actual distance and potentially save some iterations.
hope it helped :)
void transform(int[] in, int[] out, int size)
{
int[] state = in.clone();
report(state);
while (true)
{
int minPressure = 0;
int indexOfMinPressure = 0;
int maxPressure = 0;
int indexOfMaxPressure = 0;
int pressureSum = 0;
for (int index = 0; index < size - 1; ++index)
{
int lhsDiff = state[index] - out[index];
int rhsDiff = state[index + 1] - out[index + 1];
int pressure = lhsDiff - rhsDiff;
if (pressure < minPressure)
{
minPressure = pressure;
indexOfMinPressure = index;
}
if (pressure > maxPressure)
{
maxPressure = pressure;
indexOfMaxPressure = index;
}
pressureSum += pressure;
}
if (minPressure == 0 && maxPressure == 0)
{
break;
}
boolean shiftLeft;
if (Math.abs(minPressure) > Math.abs(maxPressure))
{
shiftLeft = true;
}
else if (Math.abs(minPressure) < Math.abs(maxPressure))
{
shiftLeft = false;
}
else
{
shiftLeft = (pressureSum < 0);
}
if (shiftLeft)
{
++state[indexOfMinPressure];
--state[indexOfMinPressure + 1];
}
else
{
--state[indexOfMaxPressure];
++state[indexOfMaxPressure + 1];
}
report(state);
}
}
A simple greedy algorithm will work and do the job in minimum number of steps. The function returns the total numbers of steps required for the task.
int shift(std::vector<int>& a,std::vector<int>& b){
int n = a.size();
int sum1=0,sum2=0;
for (int i = 0; i < n; ++i){
sum1+=a[i];
sum2+=b[i];
}
if (sum1!=sum2)
{
return -1;
}
int operations=0;
int j=0;
for (int i = 0; i < n;)
{
if (a[i]<b[i])
{
while(j<n and a[j]==0){
j++;
}
if(a[j]<b[i]-a[i]){
operations+=(j-i)*a[j];
a[i]+=a[j];
a[j]=0;
}else{
operations+=(j-i)*(b[i]-a[i]);
a[j]-=(b[i]-a[i]);
a[i]=b[i];
}
}else if (a[i]>b[i])
{
a[i+1]+=(a[i]-b[i]);
operations+=(a[i]-b[i]);
a[i]=b[i];
}else{
i++;
}
}
return operations;
}
Here -1 is a special value meaning that given array cannot be converted to desired one.
Time Complexity: O(n).

Counting and removing duplicates in an array c

Let's say I have an array with [2,4,6,7, 7, 4,4]
I want a program that can iterate through, and then print out something like this:
Value: Count:
2 1
4 3
6 1
7 2
I don't want it to print out ex 4 three times.
What I got so far:
for (int i = 0; i < numberOfInts; i++)
{
dub[i] = 0;
for (int y = 0; y < numberOfInts; y++)
{
if (enarray[i] == enarray[y])
{
dub[i]++;
}
}
}
So basically I check each element in the array against all the elements, and for every duplicate I add one to the index in the new array dub[].
So if I ran this code with the example array above, and then printed it out with I'd get something like this:
1,3,1,2,2,3,3. These are pretty confusing numbers, because I don't really know which numbers these belong to. Especially when I'll randomize the numbers in the array. And then I have to remove numbers so I only have one of each. Anyone got a better solution?
You can iterate through the array while checking for each element if it has been repeated in which case you increment it's count (the loop checks only values a head saving processing time). This let you accomplish what you needed without creating any extra buffer array or structure.
The bool 'bl' prevents repeated printing
int main() {
int arr[] = { 2, 4, 6, 7, 7, 4, 4 };
int size = (sizeof(arr) / sizeof(int));
printf("Value:\tCount\n");
for (int i = 0; i < size; i++) {
int count = 0, bl = 1; //or 'true' for print
//check elements ahead and increment count if repeated value is found
for (int j = i; j < size; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
//check if it has been printed already
for (int j = i-1; j >= 0; j--) {
if (arr[i] == arr[j]) {
bl = 0; //print 'false'
}
}
if (bl) { printf("%d\t\t%d\n", arr[i], count); }
}
return 0;
}
Given the char array only contains '0' to '9', you may utilize a trivial lookup table like this:
#include <stdio.h>
typedef struct
{
char c;
int num;
} TSet;
TSet my_set[] =
{
{ '0', 0 },
{ '1', 0 },
{ '2', 0 },
{ '3', 0 },
{ '4', 0 },
{ '5', 0 },
{ '6', 0 },
{ '7', 0 },
{ '8', 0 },
{ '9', 0 },
};
int main()
{
char a[] = {'2','4','6','7','7', '4','4'};
int i;
for( i = 0; i < sizeof(a) / sizeof(char); i++ )
{
my_set[ a[i] - '0' ].num++;
}
printf( "%-10s%-10s\n", "Value:", "Count:" );
for( i = 0; i < sizeof(my_set) / sizeof(TSet); i++ )
{
if( my_set[i].num != 0 )
{
printf( "%-10c%-10d\n", my_set[i].c, my_set[i].num );
}
}
}
Output:
Value: Count:
2 1
4 3
6 1
7 2
I don't understand the complexity here. I think there are two approaches that are performant and easy to implement:
Counting Sort
requires int array of size of the biggest element in your array
overall complexity O(n + m) where m is the biggest element in your array
qsort and enumeration
qsort works in O(n * log(n)) and gives you a sorted array
once the array is sorted, you can simply iterate over it and count
overall complexity O(n*log(n))
sort the array, typically by using the qsort() function
iterate over all elements counting successively equal elements and if the next different element is detected print the count of the former
This works on any number of different elements. Also no second array is needed.
You have the general idea. In addition to your input array, I would suggest three more arrays:
a used array that keeps track of which entries in the input have already been counted.
a value array that keeps track of the distinct numbers in the input array.
a count array that keeps track of how many times a number appears.
For example, after processing the 2 and the 4 in the input array, the array contents would be
input[] = { 2,4,6,7,7,4,4 };
used[] = { 1,1,0,0,0,1,1 }; // all of the 2's and 4's have been used
value[] = { 2,4 }; // unique numbers found so far are 2 and 4
count[] = { 1,3 }; // one '2' and three '4's
Put a print statement in the outer for loop to print value and repetition
for (int i = 0; i < numberOfInts; i++)
{
dub[i] = 0;
for (int y = 0; y < numberOfInts; y++)
{
if (enarray[i] == enarray[y])
{
dub[i]++;
}
}
printf("%d%d",enarray[i], dub[i]);
}
What you're asking for is strange. Normally, I'd create a struct with 2 members, like 'number' and 'count'. But let's try exactly what you're asking for (unidimensional array with each number followed by it's count):
int
i,
numberOfInts = 7,
numberOfDubs = 0,
enarray[7] = {2,4,6,7,7,4,4},
dub[14]; // sizeof(enrray) * 2 => maximum number of dubs (if there are no duplicates)
// For every number on enarray
for(i = 0; i < numberOfInts; i++)
{
int jump = 0;
// Check if we have already counted it
// Only check against pairs: Odds are the dub counter
for(int d = 0; d < numberOfDubs && !jump; d += 2)
{
if(dub[d] == enarray[i])
{
jump = 1;
}
}
// If not found, count it
if(!jump)
{
// Assign the new number
dub[numberOfDubs] = enarray[i];
dub[numberOfDubs + 1] = 1;
// We can begin from 'i + 1'
for(int y = i + 1; y < numberOfInts; y++)
{
if(enarray[i] == enarray[y])
{
dub[numberOfDubs + 1]++;
}
}
// Increment dub's counter by 2: number and it's counter
numberOfDubs += 2;
}
}
// Show results
for(i = 0; i < numberOfDubs; i += 2)
{
printf("%d repeated %d time%s\n", dub[i], dub[i + 1], (dub[i + 1] == 1 ? "" : "s"));
}

Searching array twice

This is a hackerrank problem.
Find out the maximum movies that can be watched. Assume the list to be distinct movies.
Input:
movieStart[] = {10,12,9,14,16,14}
movieEnd[] = {11,13,15,16,18,18}
Output : 4 (10-11,12-13,14-16,16-18)
Below code is giving me correct output. Would like to know the best solution possible for this problem.
Also what algorithm is used to solve this kind of problem?
static int getMaxMovies(int[] movie_start, int[] movie_end) {
int cnt = 0;
for (int i = 0; i < movie_start.length; i++) {
for (int j = 0; j < movie_start.length; j++) {
if (movie_start[j] == movie_start[i] && movie_end[j] == movie_end[i]) {
continue;
}
if (movie_start[j] >= movie_start[i] && movie_end[j] <= movie_end[i]) {
cnt += 1;
break;
}
}
}
return movie_start.length - cnt;
}
That's "Activity selection" problem - which could be easily solved with O(n) (in case of sorted input) or O(nlogn) (when input isn't sorted) greedy algorithm. If input is already sorted by finishing (end) time you should pick movies which doesn't conflict with previously selected movie.
Pseudocode:
Sort by finish times
int previouslySelectedIndex = 0;
int watchedMoviesCount = 1;
for (int i=1; i<movie_end.Length; i++)
{
if (movie_start[i] >= movie_end[previouslySelectedIndex)
{
watchedMoviesCount++;
previouslySelectedIndex=i;
}
}

Resources