twosum problem when array elements are negative - c

I am solving a leetcode problem "Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice."
I was able to solve the problem if array elements are positive.
I created a hashtable which works well for positive numbers. How can I make it to work for non-positive numbers.
#include "stdio.h"
#include "stdlib.h"
#include "assert.h"
/**
* Note: The returned array must be malloced, assume caller calls free(). [2,7,11,15]
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
//create a hashmap
int *hashmap = (int*)malloc(100000*sizeof(int));
int *retarray = NULL;
//memset all values to -1;
memset(hashmap,-1,(100000*sizeof(int)));
int i = 0;
int complement;
for(i=0;i<numsSize;i++){
complement = abs(target-nums[i]);
if(hashmap[complement]!= -1){
*returnSize = 2;
retarray = (int*)malloc(*returnSize*sizeof(int));
retarray[0] = hashmap[complement];
retarray[1] = i;
return retarray;
}
hashmap[nums[i]] = i;
}
*returnSize = 0;
return retarray;
}
int main(){
int i = 0;
// int arr[4] = {2,7,11,15};
int arr[4] = {-3,3,11,15}; //fails for this.
int *ret_arr;
int returnSize;
ret_arr = twoSum(arr,4,9,&returnSize);
assert(returnSize==2);
printf("ret array %d %d \n",ret_arr[0],ret_arr[1]);
}

Related

how can i return an array from a function

How can I return an array from a function, I am trying to perform (3*3)*(3*1) matrix multiplication using this translation function and how can i get an array out of it.
#include <stdio.h>
#include <math.h>
int* translation(int x, int y, int tx, int ty) {
static int res[3][1] = {0}, xy[3][1] = {{x},{y},{1}};
int tm[3][3] = {{1,0, tx}, {0,1,ty}, {0,0,1}};
for (int i = 0; i<3; i++) {
for (int j = 0; j<3; j++) {
res[i][0] += tm[i][j]*xy[j][0];
}
}
return res;
}
int main()
{
int *arr[3][1];
arr = translation(5, 5);
printf("%d %d %d", arr[0][0], arr[0][1], arr[0][2]);
return 0;
}
"How can I return an array from a function"
You can't.
The language has no such concept.
You'll have to return something including the length to give the user of the function the information. In C the idiomatic approach is to supply a pointer to the function and to get a value (via that pointer) in return:
size_t no_idea;
void function(void *data, &no_idea);
As a user of this function you'd have to read no_idea before judging.
you question is missing a lot of information like what you want to do with your code, the variable named xy isn't defined anywhere in your code, and so on...
but for clarification, if your result matrix is of unknown size, you can wrap your array into a struct, if you don't know what is the struct, you can refer to this small tutorial about struct in c, so your struct maybe look like something like this:
typedef struct Array_t{
size_t arrSize_x;
size_t arrSize_y;
int **arr;
}Array_t;
where arr is your matrix of unknown size which will be created dynamically and arrSize_x, arrSize_y are your matrix dimensions.
so in order to create a matrix of unknow size at compile time , you should create it dynamically in the heap memory using functions like calloc or malloc, although in C99, it allowed created arrays statically of unknown size during compile time but it's not the case with struct as the struct once defined, your array is created and you cannot do something like this:
typedef struct Array_t{
size_t arrSize_x;
size_t arrSize_y;
int arr[arrSize_x][arrSize_y];
}Array_t;
but if the size of the array is known you can do something like this:
typedef struct Array_t{
int arr[3][1];
}Array_t;
to create a dynamic array, you will find in the next example code something like this:
// rows are stored in heap memory and initiated with zeros
res.arr = (int**) calloc(res.arrSize_x, sizeof(int));
// columns are also stored in heap memory and initiated with zeros
for (int i = 0; i < res.arrSize_x; ++i) {
res.arr[i] = (int *) calloc(res.arrSize_y, sizeof(int));
}
where res.arr is a pointer pointing to an array of pointers and the next diagram may simplify my explanation where the next graph expresses the created matrix in heap memory for arr of size 3 x 1:
while if the size is known, so the explanation diagram may look like this:
and when you return, you can either return by value or by reference, but if you are going to return a struct by reference then you should declare it as static.
so you can do something like this (for clarification purposes, size of matrix is unknown):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct Array_t{
size_t arrSize_x;
size_t arrSize_y;
int **arr;
}Array_t;
Array_t translation(int x, int y, int tx, int ty) {
// create a struct holding the array
Array_t res;
res.arrSize_x = 3;
res.arrSize_y = 1;
// rows are stored in heap memory and initiated with zeros
res.arr = (int**) calloc(res.arrSize_x, sizeof(int));
// columns are also stored in heap memory and initiated with zeros
for (int i = 0; i < res.arrSize_x; ++i) {
res.arr[i] = (int *) calloc(res.arrSize_y, sizeof(int));
}
res.arr[0][0] = 1;
res.arr[1][0] = 2;
res.arr[2][0] = 3;
return res;
}
int main()
{
Array_t array;
// 1, 2, 3, 4 are dummy parameters
array = translation(1, 2, 3, 4);
printf("elements are :\n");
for (int i = 0; i < array.arrSize_x; ++i) {
for (int j = 0; j < array.arrSize_y; ++j) {
printf("%d\t", array.arr[i][j]);
}
printf("\n");
}
return 0;
}
and this is the output:
elements are :
1
2
3
but if size of matrix is known then you can do something like this (for clarification purposes, size of matrix is known):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct Array_t{
int arr[3][1];
}Array_t;
Array_t translation(int x, int y, int tx, int ty) {
// create a struct holding the array
Array_t res;
res.arr[0][0] = 1;
res.arr[1][0] = 2;
res.arr[2][0] = 3;
return res;
}
int main()
{
Array_t array;
// 1, 2, 3, 4 are dummy parameters
array = translation(1, 2, 3, 4);
printf("elements are :\n");
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 1; ++j) {
printf("%d\t", array.arr[i][j]);
}
printf("\n");
}
return 0;
}
and this is the ouput:
elements are :
1
2
3

Problem with storing value in pointer address

I managed to put the value in the pointer while in the function, However when i come back to the main i just dont get the values. Where am i wrong? sending parameters wrong? wrong allocation? Here's the code:
bool wc(int* nlines, int* nwords, int* nchars)
{
int lines=5,chars=6,words=7;
nchars = (int *) malloc(chars*sizeof(int));
*nchars = chars;
nlines = (int *) malloc(lines*sizeof(int));
*nlines = lines;
nwords = (int *) malloc(words*sizeof(int));
*nwords = words;
}
int main() {
int* chars; int* words; int* lines;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",chars,lines,words);
return 0;
}
If all you want to do is be able to set 3 int values inside a function then this is how I would so it.
#include <stdio.h>
#include <stdbool.h>
bool wc(int* nlines, int* nwords, int* nchars)
{
int lines=5,chars=6,words=7;
*nchars = chars;
*nlines = lines;
*nwords = words;
return true;
}
int main() {
int lines = 0;
int words = 0;
int chars = 0;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",chars,lines,words);
return 0;
}
If for some reason you must use pointers as shown in your example then this will do what you want.
#include <stdio.h>
#include <stdbool.h>
bool wc(int** nlines, int** nwords, int** nchars)
{
int lines=5,chars=6,words=7;
*nchars = malloc(sizeof(int));
**nchars = chars;
*nlines = malloc(sizeof(int));
**nlines = lines;
*nwords = malloc(sizeof(int));
**nwords = words;
return true;
}
int main() {
int* chars; int* words; int* lines;
int res = wc(&lines,&words,&chars);
printf("%d %d %d\n",*chars,*lines,*words);
free(chars);
free(words);
free(lines);
return 0;
}
As you can see this just means you need to add a bunch more * all over the place.
In C function input variables are passed by value, not reference. So when you assign them locally, the value in the caller scope is unaffected. E.g.
void foo(int a) {
a = 5;
}
int main() {
int b = 3;
foo(b);
// here, b is still 3
}
This is exactly what you are doing in your example, though your variables are not int, but int*.
If your input variable is a pointer though, you can change the memory that the variable points to, and this will obviously reflect in the calling scope. E.g.
void foo(int *a) {
*a = 5;
}
int main() {
int b = 3;
foo(&b);
// here, b is 5
}
In your case, you want to allocate pointers, so you want your function signature to be a pointer to a pointer. E.g.
void foo(int **a) {
*a = malloc(sizeof(int));
}
int main() {
int* b = NULL;
foo(&b);
// here, b is allocated to a valid heap area
free(b);
}

there is trace/breakpoint trap when using pointer in c

#include <stdio.h>
#include <malloc.h>
//#include "ans.c"
int *decompressRLElist(int *nums, int numsSize, int *returnSize);
int main()
{
int nums[] = {39, 1};
int length = 2;
int returnlength;
int *p = decompressRLElist(nums, length, &returnlength);
int *pp = p;
while (returnlength-- != 0)
{
putchar(*(p++)+'0');
}
system("pause");
return 0;
}
int *decompressRLElist(int *nums, int numsSize, int *returnSize)
{
int *ans = (int *)malloc(100);
int *p = ans;
*returnSize = 0;
numsSize /= 2;
while (numsSize-- != 0)
{
while ((*nums)-- != 0)
{
*(p++) = *(nums + 1);
(*returnSize)++;
}
nums += 2;
}
return ans;
}
I am working on a leetcode problem, after running the debugger there is an exception named trace/breakpoint trap occurred. It is confusing that when the length of array is shorter than 39, the error does not occur, but when equal or longer than 39, the error occurs.
One integer is usually 4 bytes, though it can be different deppending on your system, so when you allocate 100 bytes it's only good for 25 integers, you should use:
int *ans = malloc(100 * sizeof(*ans));
The malloc cast is also unnecessary.
The fact that the error only starts at array size of 39 can only be attributed to undefined behaviour.

How to declare multiple pointer-to-pointer using while in C?

I have this code:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void ft_ultimate_ft(int *********nbr)
{
printf("%d", *********nbr);
}
int main(){
/*Start of problem*/
int *a;
int **b = &a;
int ***c = &b;
int ****d = &c;
int *****e = &d;
int ******f = &e;
int *******g = &f;
int ********h = &g;
int *********i = &h;
/*end of problem*/
*********i = 42;
ft_ultimate_ft(i);
return 0;
}
I need to include pointer-to-pointer declaration in the loop (for example, while). It's needed to decrease number of declarations.
I am assuming that I have properly understood you question, which is to create a multiple pointer to a number using a loop and then assign value to it.
I wrote a piece of code that partly completes your requirement but still need to know how many layers there are after the loop.
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
void ft_ultimate_ft(int *********nbr)
{
printf("%d", *********nbr);
}
int main() {
int t = 10;
int n = 8;
void * p = &t;
for (int i = 0; i < n; i++)
{
void* * s = (void **)malloc(sizeof(void*));
*s = p;
p = s;
}
/*end of problem*/
int *********real = (int *********)p;
*********real = 42;
ft_ultimate_ft(real);
return 0;
}
Which outputs 42
The clean up part of the program is not written
PS. In your code, the pointer a is indeterminate and I do not think that your original code can work properly.

Dynamic array in c used by function

Im trying to build a dynamic array (according to the user input) using by a function. Im giving a small example of what i thought to do:
enter code here
int main()
{
int *array;
int counter=0; ) //countes how many inputs we got
*array=dynamic_array(array,counter)
return 0;
}
int *dynamic_array(int *array, int counter){
int c=0;
while(c!=-1)
{
counter++;
array=(int *)realloc(arraya(counter)*sizeof(int));
}
return(array);
}
And another qustion, if i want to use &counter- which i cannot do it on c, how can i replace it?
Thank you.
Your code is really weird, so it's hard to tell what you actually want.
You probably want something like this:
#include <stdlib.h>
#include <stdio.h>
// declare the dynamic_array function
int *dynamic_array(int *array, int counter);
int main()
{
int *array = NULL; // initialize to NULL (see realloc documentation)
// allocate an array of 10 ints
int counter = 10;
array = dynamic_array(array, counter);
array[0] = 12;
array[1] = 34;
// extend the array to 20 ints
counter = 20;
array = dynamic_array(array, counter);
printf("array[0] = %d\n", array[0]);
printf("array[1] = %d\n", array[1]);
return 0;
}
int *dynamic_array(int *array, int counter)
{
array = (int*)realloc(array, counter * sizeof(int));
return(array);
}

Resources