I am facing a problem related to dfs in C programming. I need to find Count Nodes Equal to Average of Subtree. Unfortunately, I did not find enough guides on c, so I am asking for help. This code still doesn't work and gives wrong results, so I'd appreciate it if you could point out my mistakes.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int ans=0;
int dfs(struct TreeNode* root){
if (root == NULL) return 0,0;
int left,left_count = dfs(root->left);
int right,right_count = dfs(root->right);
int totalSum = left+right+root->val;
int count = left_count + right_count + 1;
if (totalSum/count == root->val) ans++;
return totalSum,count;
}
int averageOfSubtree(struct TreeNode* root){
dfs(root);
return ans;
}
I've modified this code many times, but I've never gotten to a working code. At the output, I get the data, but it is incorrect (thanks in advance).
Some issues:
You seem to intend that your dfs function returns two int values, but this is not true. Your function is declared as returning int (one), and the comma operator will not return a tuple (like in Python), but will evaluate to the second argument.
So return 0,0; has the same effect as return 0;
And return totalSum,count; has the same effect as return count;
And int left,left_count = dfs(root->left); will not initialise left, only left_count
It is true that you need both the count and sum to be made available to the caller, and there are several ways you could do that. One is to pass pointers to int variables as arguments to dfs.
As ans is global, and is not reset to 0, the tests on Leet Code will accumulate results from previous runs with the current run. It is better to avoid the global variable all together. Instead, you could make it the return value of dfs. Or also a pointer to a variable that is passed as argument...
Corrected version:
int dfs(struct TreeNode* root, int *count, int *sum){
if (root == NULL) {
*count = *sum = 0;
return 0;
}
int left, left_count, right, right_count;
int ans = dfs(root->left, &left_count, &left) + dfs(root->right, &right_count, &right);
*sum = left + right + root->val;
*count = left_count + right_count + 1;
return ans + (*sum/(*count) == root->val);
}
int averageOfSubtree(struct TreeNode* root){
int sum, count; // Dummy
return dfs(root, &sum, &count);
}
Related
I need to find the sum of the values of its deepest leaves. This code works but not correctly.
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int sum = 0;
void dfs(struct TreeNode *root, int lvl){
if(root == NULL) return ;
int maxlvl = -1;
if(lvl > maxlvl){
maxlvl = lvl;
sum = root->val;
}
else if (lvl == maxlvl){
sum += root->val;
}
dfs(root->left, lvl+1);
dfs(root->right, lvl+1);
}
int deepestLeavesSum(struct TreeNode* root){
dfs(root,0);
return sum;
}
I suspect that the error is that I do not transfer the sum and declare it globally. But I don't really understand how to pass it to me and what I should put in the function.
There are a few issues with this code. First of all, maxlvl is always either -1 or the current level, so the else if never gets reached and instead sum is made equal to the last node that was visited. I assume that maxlvl is the deepest you want to search in the tree, so I would make it a global variable with a constant value.
Furthermore, you are supposed to sum the deepest leaves, yet there is no check to see if you have actually reached a leaf.
I will assume you also have to sum the values in nodes at the deepest search layer, and suggest this edit:
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int sum = 0;
int maxlvl = 10;
void dfs(struct TreeNode *root, int lvl){
if(root == NULL) return;
if (lvl == maxlvl || !(root->left || root->right)){
sum += root->val;
return;
}
dfs(root->left, lvl+1);
dfs(root->right, lvl+1);
}
int deepestLeavesSum(struct TreeNode* root){
dfs(root,0);
return sum;
}
Hello im trying to make a program that takes a linked list of integers and sums the squares of the int, using recursion. I have tried this so far, however i cant get the function of summin the squares to work. I dont know if using the pow() is the best way?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include<math.h>
typedef struct node
{
int value;
struct node* next;
} node;
/* terminal node at the end of the list */
node SENTINEL = {0, 0};
/* utility functions to create and free lists */
node * make_node(int v, node * q)
{
node* p = (node*) malloc(sizeof(node));
p->value = v;
p->next = q;
return p;
}
int sum_squares(node* list)
{
if(list == 0)
return 0;
else
{
return(pow(&list, 2) + sum_squares(list));
}
}
void free_node(node* p)
{
if(p == &SENTINEL)
return;
else
{
free_node(p->next);
free(p);
}
}
int main(void)
{
int sum;
node* list =
make_node(1,
make_node(2,
make_node(3,
make_node(4,
make_node(5, &SENTINEL)
)
)
)
);
sum = sum_squares(list);
printf("The sum of squares is: %d\n",sum);
free_node(list);
return 0;
}
it should equal 55 with the current numbers
There are a few things that you should edit!
In your sum_squares function, your base case checks whether current node list is equal to 0, but you should check whether it's the sentinel node.
In the recursive case, you should use pow(&list, 2). &list, however, returns the address of the argument list. What you're looking for is the integer value held in the node struct, which you get by using the -> operator. &list becomes list->value.
Finally, when you recursively call your next function, you pass it the same node. This will cause it to infinitely call itself on the same node, and never actually step through the list. Instead of just passing list again, you should pass list->next!
The changes are applied below:
int sum_squares(node* list)
{
if (list == &SENTINEL)
return 0;
return (pow(list->value, 2) + sum_squares(list->next));
}
I am trying to do a function that receives the root of a supposed BST and I want to know if the tree in question is a BST.
Problem is that, I am traveling the tree with recursion and what I'm trying to do is, put inside an array all the values of the tree. I searched for how to put a BST into an array (AddtoArray), but the answers I've found on stackoverflow and other websites didn't solve my problem. (I got seg fault).
Here's what I got so far:
#include<stdio.h>
#include<stdlib.h>
struct node{
int key;
struct node *left, *right;
};
struct node *newNode(int item){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
struct node* insert(struct node* node, int key){
if(node == NULL) return newNode(key);
if(key < node->key)
node->left = insert(node->left, key);
else if(key >= node->key)
node->right = insert(node->right, key);
return node;
}
void check(struct node *root, int *array, int i){
if(root != NULL){
check(root->left, array, i);
array[i++] = root->key;
//I tried to put i++, ++i in every place of this function (trying table test) and I realized it was too difficult to realize what to do here, I've found some functions returning an integer, the "i" in question, but they didn't work out for me.
check(root->right, array, i);
}
}
int main(){
int *array;
int array_length = sizeof(array)/sizeof(array[0]);
int i = 0;
array = (int*)malloc(array_length*sizeof(int));
struct node *root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 20);
check(root, array, i);
printf("PRINTING ARRAY TO SEE IF THE BST IS IN ARRAY:\n");
for(i = 0; i < array_length; i++){
printf("VALUE: %d ", array[i]);
}
free(array);
return 0;
}
I'd like to solve this problem WITHOUT using global variables. How can I do it?
I see two issues in your check-code and its usage (did not analyse the other functions):
First, your malloc does not work as intended, because sizeof(array)/sizeof(array[0]) will always give the same (small) value, probably 1 or 2, regardless of the size of your BST.
So you'd rather introduce a function getting the number of nodes and use this as the length for your array:
int array_length = getNrOfNodes(root); // function to be coded
int *array = malloc(array_length*sizeof(int));
Second, you pass an integral value i by value to a recursive function. As it is passed by value, any i++ will take effect only for the respective function call instance, but will not influence the other ones on the call stack. So it is very likely that the keys of the complete left part of your tree (the one before i is altered), will be written to array[0].
I'd suggest to share the array index among the function instances on the call stack. This can be achieved by passing a pointer to some i rather than passing i-s value around. And I'd introduce an internal version that does the work, because the user of the function needs not to be aware of the helper variable i:
void writeToArray_internal(struct node *root, int *array, int *i){
if(root != NULL){
writeToArray_internal(root->left, array, i);
array[*i] = root->key;
(*i)++;
writeToArray_internal(root->right, array, i);
}
}
void writeToArray(struct node *root, int *array) {
int i=0;
writeToArray_internal(root, array, &i);
}
This line here
int array_length = sizeof(array)/sizeof(array[0]);
is wrong. This only works with pure arrays, because sizeof returns the amount
of bytes of the expression/variable. Your variable array is a pointer, so
sizeof array returns you the size of a pointer and it doesn't matter where the
pointer is pointer, you always will get the same size.
Besides trying to get the number of elements of the "array" before knowing how
many nodes you have, makes no sense, because the number of elements that you need in array depend on the number of nodes, so
you've got write a function that returns you the number of nodes and then
you can allocate space for array.
Also note that your check function is not correct either. The variable i is
local to every call of check so you are going to overwrite values of the
array, because the i++ of the n-th iteration only affects the i of the
n-the iteration, the n-1-th iteration does not see that change and thus
overwrites the value of the n-th iteration.
You'll need to pass i as a pointer as well:
void check(struct node *root, int *array, size_t *i, size_t maxlen) {
if(root != NULL){
check(root->left, array, i, maxlen);
if(*i < maxlen) // checking that you don't step out of bounds
array[(*i)++] = root->key;
check(root->right, array, i, maxlen);
}
}
and the you call it like this:
size_t i = 0;
size_t nodes_number = get_number_of_nodes(root); // you have to write this function
int *array = malloc(nodes_number * sizeof *array);
if(array == NULL)
{
// error handling
// do not continue
}
check(root, array, &i, nodes_number);
I'm trying to solve this codewars kata
Basically I need to wite a programe that spits out an array/list of numbers from a perticular range (of numbers) which have k primes multiplicatively.
countKprimes(5, 500, 600) --> [500, 520, 552, 567, 588, 592, 594]
Now my program "works" as in it can print the results correctly, but if I put it in codewars' answer area (without main of course), it just runs forever.
"Error code SIGKILL : Process was terminated. It took longer than 12000ms to complete"
This is the codewars template
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// In the preloaded section are some functions that can help.
// They can be used as a small library.
// There is no file to include, only the templates below.
struct node {
int data;
struct node *next;
};
struct list {
size_t sz;
struct node *head;
};
struct list* createList();
// push data at the head of the list
void insertFirst(struct list* l, int data);
struct list* reverse(struct list* l);
void listFree(struct list* l);
// functions to write
struct list* kPrimes(int k, int start, int nd)
{
// your code
}
And this is my code
#include <stdio.h>
struct list{
int a[600];
};
int smallestPrimeFactor(int number){
int x;
for(x = 2; x < number; x++) {
if(number % x == 0) {
return x;
}
}
return number;
}
int primefactors(int ofnumber){
static int counter = 0;
int tempcounter = counter;
int nextnumber = ofnumber/smallestPrimeFactor(ofnumber);
if(nextnumber != 1) {
if(ofnumber >= nextnumber) {
counter++;
primefactors(nextnumber);
}
}
return (counter - tempcounter) + 1;
}
struct list kPrimes(int k, int start, int nd){
int x, g = 0;
struct list ls;
for(x = start; x < nd; x++){
if(primefactors(x) == k){
ls.a[g] = x;
g++;
}
}
return ls;
}
int main(int argc, int **argv){
int p = 5, s = 500, e = 600;
int j = 0;
while(kPrimes(p, s, e).a[j] != '\0'){
printf("%d\n", kPrimes(p, s, e).a[j]);
j++;
}
}
I think the culprit here is
struct list{
int a[600];
};
Maybe while reading the array, the test file is overshooting a's index past '\0'.
I thought of a way of solving that by making a a pointer to integer but doing int *a; prints out nothing.
I know there are more than one way of returning an array. Using referance, using a static array, passing an array as argument, etc. But I want to solve this codewars' way. Think it'll be a nice learning experience.
So, how should I be using
struct node {
int data;
struct node *next;
};
struct list {
size_t sz;
struct node *head;
};
to solve the problem?
You should not bother about the structure themselves, you should simply use the provided functions:
struct list* kPrimes(int k, int start, int nd){
int x, g = 0;
struct list *ls = createList(); // 1. Create the list.
// 2. Maybe check if ls != NULL...
for(x = start; x < nd; x++){
if(primefactors(x) == k){
insertFirst(ls, x); // 3. Insert at the beginning.
g++;
}
}
struct list *rls = reverse(ls); // 4. Reverse the list.
listFree(ls); // 5. Free the original list.
return rls; // 6. Return the reversed list.
}
Since the functions reverse is not documented, I can only guess that it creates a new list without modifying the old one, which is why you need to free it after.
The createList(), insertFirst(), reverse(), and listFree() functions, as well as the function that consumes the return value of your function are all provided to you, and they all work with the types struct list and struct node. How, then, do you imagine it could work if you try to use a differently-defined struct list than those existing functions use?
So yes, you should be using the struct node and struct list types provided to you -- and the handy functions for manipulating them -- rather than defining different structure types with the same tags.
For a binary search tree structure in C that cannot be changed:
struct bstnode {
int item;
struct bstnode* left;
struct bstnode* right;
};
struct bst {
struct bstnode* root;
};
How can we find the sum of values that are greater than a number(num)?
(we cannot travel the whole tree or convert this bst to an array).
the function declaration is:
int sum_greater(struct bst * t, int num)
Basically, my method is to use recursion:
when num equals item in the current node, we sum the right part of this tree.
when num greater than item in the current node and node->right is greater than num, we sum the right part of this tree.
But I dont know how to deal with the situation when current node is less than num.
You're making this a bit too complicated. Your base case is hitting a leaf node (which you already know how to handle). You have three recursion cases:
current > num
result = current +
recur on right child +
recur on left child
current = num
result = current +
recur on right child
current < num
result = recur on right child
return result
All you can do is to prune off the left subtrees that are too small as you find them. don't waste effort looking ahead: the recursion will handle that just fine.
Note that you cannot stop early dependent on the right child's value: that child may well have right-descendants with arbitrarily large values.
So the user #Prune has already pointed out the idea which consists of getting ride of sub trees that are less than the desired value.
int sum_greater(struct bst * t, int num){
struct bstnode *ptr = t->root;
if(!ptr)
return 0;
struct bst right_tree = { t->root->right };
struct bst left_tree = { t->root->left };
if(ptr->item > num)
return ptr->item + \
sum_greater(&left_tree, num) + \
sum_greater(&right_tree, num);
else // ptr->item =< num
return sum_greater(&right_tree, num);
}
For a complete example, run the code from : Full sum_greater code
how to deal with the situation when current node is less than num.
Only add the right BST in that case, when current node is less than or equal to num. Else add both left, right and the ->item.
int BST_sum_gt(const struct bstnode* node, int num) {
if (node == NULL) {
return 0;
}
if (node->item > num) {
return BST_sum_gt(node->left) + node->item + BST_sum_gt(node->left);
}
return BST_sum_gt(node->left);
}
int sum_greater(const struct bst * t, int num) {
return BST_sum_gt(t->root);
}
Or a less recursive approach
int BST_sum_gt(const struct bstnode* node, int num) {
int sum = 0;
while (node) {
if (node->item > num) {
sum += BST_sum_gt(node->left) + node->item;
}
node = node->right;
}
return sum;
}