In an interview I was asked the following question. I am given two arrays, both of them are sorted.
BUT
Array 1 will have few -1\'s and Array 2 will have to
You should do something like insertion sort. As both the arrays are sorted (except -1s), the smallest number in array2 will be placed somewhere between first element and the first -1, 2nd element of array2 will be placed somewhere anywhere after the 1st -1 in array1 and before or at the 2nd -1 in array1 and so on.
So you have to insert a particular element of array2 in only a segment of array1 and not the whole array. Also each element of array2 have to consider different segment or subarray of array1. So, effective time complexity of this logic will be O(n+m) where n is the length of array1 and m is the length of array2.
Let me re-phrase three most important aspects of the task:
Pseudo logic:
Code example:
public static void AMerge()
{
int[] array1 = new int[] { 3, 6, -1, 11, 15, -1, 23, 34, -1, 42 };
int[] array2 = new int[] { 1, 9, 28 };
int[] arrayMerged = new int[array1.Length];
int array1Index = 0;
int array2Index = 0;
for (int arrayMergedIndex = 0; arrayMergedIndex < array1.Length; arrayMergedIndex++)
{
while (array1[array1Index] == -1) array1Index++; //ignore -1 placeholders
if ((array1Index < array1.Length && array2Index >= array2.Length)
|| array1[array1Index] <= array2[array2Index]) //choose which array will provide current merged value
{
arrayMerged[arrayMergedIndex] = array1[array1Index];
array1Index++;
}
else
{
arrayMerged[arrayMergedIndex] = array2[array2Index];
array2Index++;
}
}
char[] charsToTrim = { ',', ' '};
string arrayMergedString = "{";
foreach (int f in arrayMerged) arrayMergedString += f.ToString() + " ";
arrayMergedString = arrayMergedString.TrimEnd(charsToTrim) + "}";
Console.WriteLine(arrayMergedString);
Console.ReadKey();
}
}
Note:
You can try following approach:
arrayTwo and keep it in a variable say val.arrayOne and check if current value is greater than val, push it in array and decrement value of i by 1 to check next value as well with current element.0, ignore it, else push value to array.function mergeAndSort(a1, a2) {
var matchCount = 0;
var ret = [];
for (var i = 0; i < a1.length; i++) {
var val = a2[matchCount];
if (a1[i] > val) {
ret.push(val)
matchCount++
i--;
continue;
}
if (a1[i] > 0) {
ret.push(a1[i]);
}
}
console.log(ret.join())
return ret;
}
var arrayOne = [3, 6, -1, 11, 15, -1, 23, 34, -1, 42]
var arrayTwo = [7, 19, 38];
var arrayThree = [1, 9, 28];
var arrayFour = [1,2,5]
mergeAndSort(arrayOne, arrayTwo)
mergeAndSort(arrayOne, arrayThree)
mergeAndSort(arrayOne, arrayFour)
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
Note: Not putting check for number of elements in arrayTwo as its clearly mentioned in question that it will be same.
There is a clean O(N) in-place solution.
First "pack" arrayOne by moving all -1 (-- below) to the front. This takes a single backward pass.
Then perform a merge by iteratively moving the smallest element among arrayTwo and the tail of arrayOne and overwriting the next --. The gap will narrow down but there will always remain room for the elements of arrayTwo.
3, 6, --, 11, 15, --, 23, 34, --, 42
1, 9, 28
Packing:
3, 6, --, 11, 15, --, 23, 34, --, 42
3, 6, --, 11, 15, --, 23, --, 34, 42
3, 6, --, 11, 15, --, --, 23, 34, 42
3, 6, --, 11, --, --, 15, 23, 34, 42
3, 6, --, --, --, 11, 15, 23, 34, 42
3, --, --, --, 6, 11, 15, 23, 34, 42
--, --, --, 3, 6, 11, 15, 23, 34, 42
Merging:
--, --, --, 3, 6, 11, 15, 23, 34, 42
1, 9, 28
1, --, --, 3, 6, 11, 15, 23, 34, 42
--, 9, 28
1, 3, --, --, 6, 11, 15, 23, 34, 42
--, 9, 28
1, 3, 6, --, --, 11, 15, 23, 34, 42
--, 9, 28
1, 3, 6, 9, --, 11, 15, 23, 34, 42
--, --, 28
1, 3, 6, 9, 11, --, 15, 23, 34, 42
--, --, 28
1, 3, 6, 9, 11, 15, --, 23, 34, 42
--, --, 28
1, 3, 6, 9, 11, 15, 23, --, 34, 42
--, --, 28
1, 3, 6, 9, 11, 15, 23, 28, 34, 42
--, --, --
Couldn't it be something like
compare each item of arrayTwo with each item of arrayOne If it comes to bigger that that of arrayOne, insert the item and while iterating arrayOne delete all the -1 .
You should use merge function from Merge sort, and modify it so that it doesn't create a new array, but instead uses array1, and perform translation, after insertion of an element from array2, that will shift elements to the right until the next -1, and thus overwrite the -1.