I am doing an problem on Leetcode. The question is that given an array and a value, remove all instances of that value in place and return the new length.
Or you can read it here:
int removeElement(int* nums, int numsSize, int val) {
int *nums_copy;
int count = 0;
int actual_count = 0;
while (actual_count < numsSize) {
if (nums[actual_count] != val) {
nums_copy[count] = nums[actual_count];
count++;
nums_copy = realloc(nums_copy, sizeof(int)* count);
}
actual_count++;
}
nums = nums_copy;
return actual_count;
}
When I tried to test it with [1, 2, 2, 3], 2, the output is [1, 2, 2, 3] while the expected output is [1, 3].
Firstly, you don't need to realloc, the problem says to remove the value in place. Secondly, what you need to do is to simply walk through the array and shift it one position to the left when you encounter the searched value. And decrement the resulted count.
The problem does not need to memory allocation. All that is needed is to have the matching elements towards the end of the list. Here is an example.
array = 3, 2, 5, 2, 7, 2
len = 6
val = 2
We want to achieve something like
array = 3, 7, 5, 2, 2, 2
newlength = 3
SOLUTION One approach is the following
Repeat:
Start with two marker (either index or pointer) one pointing to the leftmost and one pointing to the rightmost element
3, 2, 5, 2, 7, 2
L R
Move the left marker to the right if it matches to 'val'. Do it until the matching stops or it reaches the right marker.
3, 2, 5, 2, 7, 2
L R
(Opposite for right marker.) Move the right marker to the left if it matches to 'val'. Do it until the matching stops or it reaches the left marker.
3, 2, 5, 2, 7, 2
L R
Swap the elements corresponding to the left and right markers.
3, 7, 5, 2, 2, 2
L R
Go to Repeat.
Apparently, you have not specified how much memory you want to allocate after int *nums_copy. Use malloc from stdlib to allocate variable amount of memory on heap, or alloca to allocate on stack, but bear this in mind.
Here this should work:
int removeElement(int* nums, int numsSize, int val) {
int countNums = 0;
int countCpy = 0;
while (countNums < numsSize) {
if (nums[countNums] != val) {
// Copy the number.
nums[countCpy] = nums[countNums];
++ countCpy;
}
++ countNums;
}
return countCpy;
}
As for why this output you got was [1, 2, 2, 3], I don't really understand. As you're trying to set nums_copy[0] before having allocated nums_copy, you should be getting a segfault. I suppose it's due to the platform you're coding on.
The given code uses std::vector, so why not use its build-in functions?
int removeElement(vector<int>& nums,int val){
vector<int> newNums();
for (int i=0; i<nums.size(); i++){
if (nums[i]!=val){
newNums.push_back(nums[i]);
}
}
return newNums.size();
}
int removeElement(int* nums, int numsSize, int val) {
int i, j;
for(i = 0, j = 0 ; i < numsSize ; i++){
if( nums[i] == val ) continue;
nums[ j ] = nums[ i ]; // blind copy
j++;
}
/*
nums = realloc( nums, j * sizeof( int ) );
*/
return j; //actual_count
}
Related
I am stuck in this question for long time.
the question is - to move duplicates to the end of the array while preserving the order(time complexity must be O(nlogn)).
limitation:
order must be preserved.
can use only 1 helper array
the range of values in the array are not known and can be really large from n(which is the size fo the array).
values are positives.
time complexity - nlogn
example:
arr = {7, 3, 1, 2, 7, 9, 3, 2, 5, 9, 6, 2}, n = 12
result:
arr = {7, 3, 1, 2, 9, 5, 6, 2, 9, 2, 3, 7}
this what i did right now but i am stuck from thier:
copied original array to temp array
sort the temp array using quick sort
move duplicate to the end in temp array
i know that i need to do some comparison with the original array but this the part that i am stuck.
code:
int findDulpilcatesV2(int* arr, int n) {
int i, * tempArr, j = 0, countNonRepeatEl = 0, searchKeyIndex, elIndex;
tempArr = (int*)calloc(n, sizeof(int));
assert(tempArr);
// Saving original array in temp array
for (i = 0; i < n; i++)
{
tempArr[i] = arr[i];
}
// Sorting temp array
quickSort(tempArr, 0, n - 1);
// Move duplicates to the end
for (i = 0; i < n; i++)
{
if (tempArr[i] != tempArr[i+1])
{
swap(&tempArr[j], &tempArr[i]);
countNonRepeatEl++;
j++;
}
}
free(tempArr);
tempArr = NULL;
return countNonRepeatEl;
}
I'd like to ask for a help regarding the function which has to return a value of the array element which does not have a matching pair.
For instance,
a) In the array [1, 1, 2, 3, 4, 3, 4], the element without a pair is 2.
b) In the array [1, 1, 2, 4, 3, 4, 2, 3, 4], the element without a pair is 4.
So far I come up with the code below. So basically it checks for the repetitive numbers, and thus works for the b) case; yet it doesn't works for the a) case. Any help regarding how to fix this code, so that it works for a) and b) cases, is welcome.
#include <stdio.h>
int ft_unmatch(int *tab, int length)
{
int i;
int j;
int count;
i = 0;
while (i < length)
{
j = i + 1;
count = 0;
if (tab[i] == tab[j])
{
count++;
while (j < length)
{
if (tab[i] == tab[j])
count++;
j++;
}
if (count % 2 != 0)
return (tab[i]);
}
i++;
}
return (tab[i]);
}
int main(void)
{
//some additional arrays to check the function
int tab[9] = {1, 1, 2, 4, 3, 4, 2, 3, 4};
//int tab[11] = {1, 1, 2, 4, 3, 1, 4, 2, 4, 3, 4};
// int tab[7] = {1, 1, 2, 3, 4, 3, 4};
printf("%d\n", ft_unmatch(tab, 9));
return (0);
}
Assuming that all elements in the array are integer numbers and have a matching pair except one, just keep XORing the elements until the last one. Your result at the end of the scan will be the unmatched element.
The reason why this works is that:
XOR is commutative (so a XOR b = b XOR a)
for every a, a XOR a = 0
for every a, 0 XOR a = a
Every element will be cancelled out by their matching pair except one: the one you are looking for.
example:
int result=0;
for (i = 0; i < length; i++) {
result = result ^ tab[i];
}
return result;
Then handle edge cases as you wish.
Many problems in this code:
You compare every number with all of the following ones. So in a), you compare the first 1 with all the other numbers and count two 1s, but then you count the second 1 again and won't find another, so you code returns 1.
Also, you are missing curly brackets following the if tab[i] == tab[j]) and you only get to the while(j<length)-loop if the first if(tab[i] == tab[j]is true.
One possible solution would be to remove the numbers that were already counted from the array, so you don't count them again, or sort the array and count until each increment. If you are only working with small numbers you could also iterate over every possible number and count how often it appears, although that would be less elegant.
I have a simple function in C to get whether an array is sorted, but I seem to be getting different values every time. Sometimes I get 3 tests passed and sometimes I get 2 tests passed and am unsure what the problem is.
int is_sorted(int a[], int n)
{
for(int i = 0; i < n; i++)
{
if(a[i] > a[i + 1])
{
return 0;
}
}
return 1;
}
int main()
{
int a[] = {2, 4, 9, 8, 12};
int b[] = {-5, -2, 0, 8, 11, 15};
int aa[] = {2, 18, 12, 9, 1, 2, 8, 11, 16, 3};
int c[] = {4, 6, 8, 10};
npassed = 0;
if(!is_sorted(a, 5))
{
npassed++;
}
if(is_sorted(b, 6))
{
npassed++;
}
if(!is_sorted(aa, 10))
{
npassed++;
}
if(is_sorted(c, 5))
{
npassed++;
}
printf("number passed is_sorted : %i\n", npassed);
}
your function accepts two arguments:
a: the array
n: the arrays size
to check if it is sorted you iterate over all elements and see if its next element is bigger than itself. To do that, you count with i from zero (the lowest possible index) to n-1 (the highest possible index).
But you always check if i is greater than i+1. And what happens if you reach the last possible index for i? Then i+1 is equal to n and therefore outside the array. And what's outside your array is random data.
I have the following (incomplete) function:
/* Populates char* name with the named location of the ith (flat) element
* of an array with ndim dimensions where the length of each dimension
* is already stored in the int* dim.
*
* name: a pointer to where the name should be populated
* n: the base name of the array
* dim: an int[] containing the length of each dimension
* ndim: length of the dim array
* i: name of the iteration variable being used
**/
void populateName(char *name, const char *n, int *dim, int ndim, const char *i) {
strcpy(name, n);
char *loc = (char*)(name + strlen(n));
char *curr;
for (int k = 0; k < ndim; k++) {
...
sprintf(loc, "[%s]", curr);
loc += strlen(loc);
}
}
What should go in the "..." in the for loop? For example, calling populateName() with:
int dim[2] = {3, 4};
char name[1024];
populateName(name, "x", dim, 2, "i");
should result in something like:
name = "x[i / 3][i % 4]"
or some other valid name for accessing the ith location in an array defined as:
int x[3][4];
Context: I'm writing a C program which generates C programs which filter large amounts of data based on user-defined data types and rules written in an IDL.
Edit: A python function which returns a tuple containing the location / coordinates in the array might get me going in the right direction. In particular the following array should have each element correspond with it's flat position in the array (using pylab here):
In [14]: x
Out[14]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]],
[[12, 13, 14],
[15, 16, 17]]])
In [15]: x.flat.copy()
Out[15]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
A good approach to solve a problem like this one is to try out a few examples. Consider the following picture that shows the memory layout for a 3D array x[2][3][5]:
How can we convert offset 14 to position x[0][2][4]? Well, first, we see that each x[i] holds 15 (3*5) blocks, so first of all we determine to which block does 14 belong to, by computing the integer division 14/15 = 0. So, offset 14 is somewhere inside x[0].
We can now apply the same method. x[i][j] holds 5 blocks, so offset 14 belongs to block number 14/5 = 2. In fact, the correct calculation is (14/5)%3, as we will see for offset 18. And finally, x[i][j][k] holds single blocks, so the last index is given by 14%5. Think of it like this: we are interpreting these blocks of memory as if they had different sizes at each step. First, we assume everything is divided in chunks of 15 elements. Then, we assume everything is divided in chunks of 5 elements.
You can play with this example and see that offset 18 maps to x[1][0][3] because 18/15 = 1; (18/5)%3 = 0, and 18%5 = 3.
It can be seen that the general case is that for dimension n, we interpret the memory layout as if it was organized in j blocks, where j is the product of every dimension greater than n, so we have to index position (i/j)%n.
Here's my implementation:
void populateName(char *name, const char *n, int *dim, int ndim, const char *i) {
strcpy(name, n);
char *loc = (char*)(name + strlen(n));
int j;
int *mul = malloc(sizeof(int)*ndim);
mul[ndim-1] = 1;
/* Compute cumulative multipliers array */
for (j = ndim-2; j >= 0; j--) {
mul[j] = mul[j+1] * dim[j+1];
}
for (j = 0; j < ndim; j++) {
loc += sprintf(loc, "[(%s/%d)%%%d]", i, mul[j], dim[j]);
}
free(mul);
}
As you can see, it uses a cumulative array of multipliers, where mul[i] holds the product of every dimension greater than i.
By the way, you don't need curr; since sprintf returns the number of characters printed, we just have to move loc that same amount. It gets a little more efficient than calling strlen repeatedly after sprintf.
I don't have much time to test this, but with the example I showed, I get this:
x[(i/15)%2][(i/5)%3][(i/1)%5]
Which looks correct. Here's an example program:
int main()
{
int dims[] = { 2, 3, 5, 7, 9 };
char name[1024];
populateName(name, "x", dims, 5, "i");
printf("%s\n", name);
return 0;
}
This prints:
x[(i/945)%2][(i/315)%3][(i/63)%5][(i/9)%7][(i/1)%9]
It gets trickier to read for arbitrary n dimensional arrays, but the principle is always the same.
Let's say I have an array a of length n and a second array indices, also of length n. indices contains some arbitrary permutation of the sequence [0, n). I want to to rearrange a such that it's in the order specified by indices. For example, using D syntax:
auto a = [8, 6, 7, 5, 3, 0, 9];
auto indices = [3, 6, 2, 4, 0, 1, 5];
reindexInPlace(a, indices);
assert(a == [5, 9, 7, 3, 8, 6, 0]);
Can this be done in both O(1) space and O(n) time, preferably without mutating indices?
With mutating indices :(. Without looks hard (see stable in-place mergesort).
a = [8, 6, 7, 5, 3, 0, 9]
indices = [3, 6, 2, 4, 0, 1, 5]
for i in xrange(len(a)):
x = a[i]
j = i
while True:
k = indices[j]
indices[j] = j
if k == i:
break
a[j] = a[k]
j = k
a[j] = x
print a
This is what I call a "permute from" algorithm. In C-like language it would look as follows
for (i_dst_first = 0; i_dst_first < n; ++i_dst_first)
{
/* Check if this element needs to be permuted */
i_src = indices[i_dst_first];
assert(i_src < n);
if (i_src == i_dst_first)
/* This element is already in place */
continue;
i_dst = i_dst_first;
pending = a[i_dst];
/* Follow the permutation cycle */
do
{
a[i_dst] = a[i_src];
indices[i_dst] = i_dst;
i_dst = i_src;
i_src = indices[i_src];
assert(i_src != i_dst);
} while (i_src != i_dst_first);
a[i_dst] = pending;
indices[i_dst] = i_dst;
}
Note though that this algorithm destroys the index array. I call it "permute from" since the index[i] value specifies from where to take the i-th element of the resultant sequence.
Note also, that the number of "element move" operations required for in-place permutation of a sequence is equal to number of misplaced elements + number of cycles in the permutation. This algorithm achieves this limit, so in terms of the number of moves no better algorithm is possible.
Potential problem with this algorithm is that it is based on "juggling" approach, making its cache behavior far from optimal. So, while this algorithm is the best one in theory, it could lose to some more "practical" algorithms in real life.
One can also implement a "permute to" algorithm, where index[i] value specifies where to relocate the original i-th element.
If a is an array of integers, then an O(n)-time, O(1)-space algorithm is possible that keeps the order of permutation indices. In this case we can permute a into indexes and use a as a temporary storage of the inverse permutation. After the permutation is performed, the arrays a and indices are swapped, and indices is inverted in situ using e.g. algorithm J from TAoCP. The following is a working Java program:
int [] a = {8, 6, 7, 5, 3, 0, 9};
int [] indices = {3, 6, 2, 4, 0, 1, 5};
int n = indices.length;
int i, j, m;
// permute a and store in indices
// store inverse permutation in a
for (j = 0; j < n; ++j) {
i = indices[j]; indices[j] = a[i]; a[i] = j;
}
// swap a and indices
for (j = 0; j < n; ++j) {
i = indices[j]; indices[j] = a[j]; a[j] = i;
}
// inverse indices permutation to get the original
for (i = 0; i < n; ++i) {indices[i] = -indices[i] - 1;}
for (m = n - 1; m >= 0; --m) {
// for (i = m, j = indices[m]; j >= 0; i = j, j = indices[j]) ;
i = m; j = indices[m];
while (j >= 0) {i = j; j = indices[j];}
indices[i] = indices[-j - 1];
indices[-j - 1] = m;
}
This answers the question when indices array is mutable.
Here is a solution when it is not mutable.
void mutate(int[] input, int[] indices) {
int srcInd;
for (int tarInd = 0; tarInd < input.length; tarInd++) {
srcInd = indices[tarInd];
while(srcInd < tarInd) {
// when src is behind, it will have it's final value already and the original
// value would have been swapped with src's src pos. Keep searching for the
// original value until it is somewhere ahead of tarInd.
srcInd = indices[srcInd];
}
swap(input, srcInd, tarInd);
}
}
I think the classic way to deal with this problem is to work round the cycles, and to do this you need a marker bit per data item from somewhere. Here I pinched the top bit of the index array, which you could restore - of course this assumes that you don't have -ve array indexes or are using all bits of an unsigned number as an index. One reference for this is Knuth Volume 1 section 1.3.3 answer to question 12, which deals with the special case of transposing a matrix. Knuth gives references to slower in-place methods. The paper "Permuting in Place" by Fich, Munro, and Poblete claims nlogn time and O(1) space in the worst case.
import java.util.Arrays;
public class ApplyPerm
{
public static void reindexInPlace(int[] rearrangeThis, int[] indices)
{
final int TOP_BIT = 0x80000000;
for (int pos = 0; pos < rearrangeThis.length; pos++)
{
if ((indices[pos] & TOP_BIT) != 0)
{ // already dealt with this
continue;
}
if (indices[pos] == pos)
{ // already in place
continue;
}
// Now shift an entire cycle along
int firstValue = rearrangeThis[pos];
int currentLocation = pos;
for (;;)
{
// pick up untouched value from here
int replaceBy = indices[currentLocation];
// mark as dealt with for the next time we see it
indices[currentLocation] |= TOP_BIT;
if (replaceBy == pos)
{ // have worked our way round
rearrangeThis[currentLocation] = firstValue;
break;
}
if ((replaceBy & TOP_BIT) != 0)
{
throw new IllegalArgumentException("Duff permutation");
}
// Move value up
rearrangeThis[currentLocation] = rearrangeThis[replaceBy];
// and fill in source of value you have just moved over
currentLocation = replaceBy;
}
}
}
public static void main(String[] s)
{
int[] a = new int[] {8, 6, 7, 5, 3, 0, 9};
int[] indices = new int[] {3, 6, 2, 4, 0, 1, 5};
reindexInPlace(a, indices);
System.out.println("Result is " + Arrays.toString(a));
}
}
You can do this by hiding the values in the real array. By this way you can do this in both O(1) space and O(n) time.
Basically, you traverse through your indices array first, store the value of the indice array in the correct position. Now this can be done in the algorithm of your choice. For me, I would simply store the number's trailing bits from the Most Significant bit position. Do this in one traversal. Now the base array would be messed up.
During the second traversal store all the upper half bits to lower half.
The obvious disadvantage of this technique is that the stored integer
value can hold as much as half the bits. Meaning if you are dealing
with 4 byte integer, the values can only be of 2 bytes. However instead of using up half the array as show in the code below, it can be enhanced by using a better algorithm where you hide the value in the index array. Here you will require the max bits reserved in worst case would be the length of the array rather than constant 16 in the previous case. It will perform worst than the former when the length exceeds 2 power 16.
import java.util.Arrays;
class MyClass {
public static void main(String[] args) {
MyClass myClass = new MyClass();
int[] orig_array = {8, 6, 7, 5, 3, 0, 9};
int[] indices = {3, 6, 2, 4, 0, 1, 5};
myClass.meth(orig_array, indices);
}
public void meth(int[] orig_array, int[] indices){
for(int i=0;i<orig_array.length;i++)
orig_array[i] += orig_array[indices[i]] + orig_array[indices[i]] << 15 ;
for(int i=0;i<orig_array.length;i++)
orig_array[i] = orig_array[i] >> 16;
System.out.print(Arrays.toString(orig_array));
}
}
Here's a C++ version (it modifies the indices):
#include <algorithm>
#include <iterator>
template<class It, class ItIndices>
void permutate_from(
It const begin,
typename std::iterator_traits<It>::difference_type n,
ItIndices indices)
{
using std::swap;
using std::iter_swap;
for (typename std::iterator_traits<It>::difference_type i = 0; i != n; ++i)
{
for (typename std::iterator_traits<ItIndices>::value_type j = i; ; )
{
swap(j, indices[j]);
if (j == i) { break; }
iter_swap(begin + j, begin + indices[j]);
}
}
}
Example:
int main()
{
int items[] = { 2, 0, 1, 3 };
int indices[] = { 1, 2, 0, 3 };
permutate_from(items, 4, indices);
// Now items[] == { 0, 1, 2, 3 }
}
JavaScript version
var input = [1,2,3,4,5],
specArr = [0,2,1,4,3];
function mutate(input, specArr) {
var visited = [0,2]
for(var i=0; i<specArr.length; i++) {
var tmp;
//keep track of array items we've already looped through (wouldn't want to mutate twice :D)
visited.push(specArr[i]);
// if index hasn't changed we do nothing to input arr
if (visited.indexOf(1) < 0) {
// if it has changed temporarily store the value
tmp = input[i];
//swap input array item with spec item
input[i] = input[specArr[i]];
//swap specced array item with input item above
input[specArr[i]] = tmp;
}
}
}
mutate(input, specArr);