How to maintain values in recursive calls? - recursion

Let us su[ppose,we have a bidirectional graph as shown below
Now, it's DFS Traversal from source 8 will be 8 1 2 3 6 7 4 5.
The recursive implementation
vector <int> v[10001];
bool visited[10001];
void DFS(int s)
{
visited[s]=true;
cout<<s<<" ";
for(int i=0;i<v[s].size();i++)
{
if(!visited[v[s][i]])
{
DFS(v[s][i]);
}
}
}
So first it will recursively go as 8->1->2->3 , 8->6 , 8->7->4->5
Now,using this function, i also want to keep the track of distance of every node from it's source.
Let us call this as dist[N] where N=number of nodes.
In this graph
dist[8]=0,
dist1=1,
dist[2]=2
and so on. How can i implement this?
At first i tried keeping a variable d and incrementing it as shown in the code below
int d=0;
void DFS(int s)
{
visited[s]=true;
cout<<s<<" ";
dist[s]=d;
d++;
for(int i=0;i<v[s].size();i++)
{
if(!visited[v[s][i]])
{
DFS(v[s][i]);
}
}
}
But obviously,the value of d has to be reset to 0 when it reaches 8 again ,other wise dist[6] will be 1+ dist[3] according to above function . How to overcome this ? Also , is there some more efficient way to achieve this?

Instead of having a global variable tracking depth, it can be a parameter to the next iteration.
void DFS(int s, int d)
{
visited[s]=true;
cout<<s<<" ";
dist[s]=d;
for(int i=0;i<v[s].size();i++)
{
if(!visited[v[s][i]])
{
DFS(v[s][i], d+1);
}
}
}

Related

Storing pre-order traversal of a tree in vector

I was trying to store my pre order traversal in a vector.
First i tried this.
vector<int> s;
vector <int> preorder(Node* root)
{
if(root==NULL)
return s;
s.push_back(root->data);
preorder(root->left);
preorder(root->right);
return s;
}
And it gave me wrong answer but later when i tried this
void pre(Node* root,vector<int>& s)
{
if(root==NULL)
return;
s.push_back(root->data);
pre(root->left,s);
pre(root->right,s);
}
vector <int> preorder(Node* root)
{
vector<int> s;
pre(root,s);
return s;
}
I got correct answer.I am not getting why my first code was giving me WA.
(How can i do this in one function?)

Having problem in conversion from Recursive solution to DP

Given a Binary Tree of size N, find size of the Largest Independent Set(LIS) in it. A subset of all tree nodes is an independent set if there is no edge between any two nodes of the subset. Your task is to complete the function LISS(), which finds the size of the Largest Independent Set.
I came up with this recursive solution.
int rec(struct Node *root,bool t)
{
if(root==NULL)
return 0;
if(t==true)
{
return max(1+rec(root->left,!t)+rec(root->right,!t),rec(root->left,t)+rec(root->right,t));
}
else
{
return max(rec(root->left,!t)+rec(root->right,!t),rec(root->left,t)+rec(root->right,t));
}
}
int LISS(struct Node *root)
{
int x,y;
y=rec(root,true);
return y;
}
To solve this problem via DP, I modified the code as follows, but then it gives wrong answer.
It doesn't even work with Binary tree with distinct elements.
map<int,int> mm;
int rec(struct Node *root,bool t)
{
if(root==NULL)
return 0;
if(mm.find(root->data)!=mm.end())
return mm[root->data];
if(t==true)
{
mm[root->data]=max(1+rec(root->left,!t)+rec(root->right,!t),rec(root->left,t)+rec(root->right,t));
return mm[root->data];
}else
{
mm[root->data]=max(rec(root->left,!t)+rec(root->right,!t),rec(root->left,t)+rec(root->right,t));
return mm[root-s>data];
}
}
int LISS(struct Node *root)
{
//Code here
mm={};
int y=0;
y=rec(root,true);
return max(x,y);
}
What's the mistake?
You have two states in your function but you are memoizing only one state. Let's say for root x,
rec(x,true) = 5 and
rec(x,false) = 10 .
You calculated the rec(x, true) first and saved it in your map "mm" as mm[x] = 5.
So when you are trying to get the value of rec(x, false) it is getting the value of rec(x, true) which is 5.

How to find connected friends in a social media using java steam

In a social media, suppose each user is represented like below:
public class User {
private int userId;
private List<User> friendsList;
User(int id) {
this.userID = id;
this.friendsList = new LinkedList<>();
}
void addFriend(User a) {
this.friendsList.add(a);
}
int getUserId() {
return this.userID;
}
List<User> getFriendsList() {
return this.friendsList;
}
}
if A and B are friends(A->B), then A will be added to B's friend list and B will be added to A's friend list.
A.addFriend(B);
B.addFriend(A);
How i can efficiently find two users X and Y are connected by using Java 8 steam methods ?
ie if X->p->q->r->s->Y, then
bool isConnected(User X, User Y) should return true
Here X and Y are connected through common friends p, q, r and s.
You would need a way to keep track of the object that was visited or else you will go in loops.
public bool NodeVisited { get; private set; }
boolean isConnected(User a, User b){
for(final User u : a.getFriendsList()){
if(NodeVisited == false){
NodeVisited = true;
if(u.getUserId() == b.getUserId() || isConnected(u, b)){
return true;
}
}
else continue;
}
return false;
}
The close problem to "Find the shortest way (if any) between 2 points in a labyrinth."
Main idea:
Spread 2 waves from 2 points (or 2 friends) which cover near points (friends)
Remember only(!) previous layers of points (friends) to restrict the future spreading out of the wave in that directions
After each spreading out step check wawes intersection for common points (friends)
Repeat until getting intersections of waves or 1 wave will be stopped:
there are no new directions to spread except in backward directions from the previous step.
P.S.:
The most optimal algorithm involves "several" (depends on data) spots of wave spreading processes.
https://github.com/Dimoniada/FriendsProblem
You don't really have to use streams, but just a simple for-loop and recursion:
boolean isConnected(User a, User b){
for(final User u : a.getFriendsList()){
if(u.getUserId() == b.getUserId() || isConnected(u, b)){
return true;
}
}
return false;
}
If you still want to use streams, you can use this snippet (still uses recursion though):
boolean isConnected(User a, User b){
return a.getFriendsList()
.stream()
.anyMatch(u -> u.getUserId() == b.getUserId() || isConnected(u, b));
}

Need some support in writing factorial function using Recursion

I need to write a factorial function that takes in one input and returns the factorial of the given number. if the function is passed in to be 0 or less than 0 then the function should return 0.
I am not actually sure how to write this only using the features of PSScript version 1.0 however I just wrote this, please can someone help me.
JAVA -
public static int factorial (int n) {
if (n<0) {
return 0;
}
return (n<2) ? 1 : n *factorial(n-1);
}
I want to know if there is any I could write this so could use this to write a function in PSScript version 1.0
This is what I have done so far ;
func fac (int n) return int {
if (n<0){
return 0;
}
else
{
return (n<2) ? 1 : n *factorial(n-1);
}
}
Based on the language spec you linked to I would guess the recursive factorial function would look like this in your fictional language:
func fac (int n) returns int {
if (n == 0) {
return 1;
} else {
return n * fac(n - 1);
}
}
Maybe it should check for negative arguments too.

Using recursion to sum numbers

I have just been studying the concept of recursion and I thought that I would try a simple example. In the following code, I am attempting to take the numbers: 1, 2, 3, 4, 5, and add them together using recursion. I expected the result to be 15, but my code is returning 16.
What am I doing wrong?
Code:
static void Main(string[] args)
{
Console.WriteLine(Sum(5));
Console.Read();
}
static int Sum(int value)
{
if (value > 0)
{
return value + Sum(value - 1);
}
else
{
return 1;
}
}
You're returning 1 in the else clause. You should be returning 0:
else
{
return 0;
}
If the value is not greater than zero, why would you return one in the first place?
Your code executes as follows:
Sum --> 5
Sum --> 4
Sum --> 3
Sum --> 2
Sum --> 1
Sum --> 0
1 <---
2 <---
4 <---
7 <---
11 <---
16 <---
Check your base case.
Others already noted the error, and I will elaborate on recursion.
Although C# does not currently perform tail call optimization (although IL has special tail instruction), it's worth mentioning that tail recursion is generally a good thing.
Tail recursion is a special case of recursion in which the last operation of the function, the tail call, is a recursive call. Since the last call is the recursive call there is no need to preserve stack frame of the calling function and the compiler can easily use this information to generate machine instruction such that the stack doesn't grow at all. So it can basically turn recursive function into an iterative one.
Rewriting your code to support tail recursion can be done as follws:
static int Sum(int result, int value)
{
if(value == 0)
return result;
return Sum(result + 1, value - 1);
}
static int Sum(int value)
{
if (value > 0)
{
return value + Sum(value - 1);
}
else
{
return 0; //Change this.
}
}
That's because, when the value is = 0, you return 1. Then it get's added.
Sum's "else" clause should return 0.
I always prefer to put the terminating case(s) up front so they're obvious, and I have a violent near-psychopathic hatred of "if cond then return a else return b" constructs. My choice would be (making it clear that it won't work properly for negative numbers):
static unsigned int Sum(unsigned int value) {
if (value == 0)
return 0;
return value + Sum(value - 1);
}
I believe that's far more readable than a morass of braces and control flow.
The others have already answered that question, but when I work with recursion, one of the things I like to do to check that it works is to use check the base case and one additional case. I your case I would test it with 1, which would yield 2. Since this is obviously wrong you might want to check for 0 which is not going to use any recursion and so it should be obvious that the error lies in the base class.
In general recursion is easier to reason about, since you can list the limited number of things you need to check, but it does initially require a leap of faith since your intuition will be wrong. Just test the edge cases and trust the math it will never fail.
int summation(int num){
if (num==1)
return 1;
return summation(num-1)+num;
}
I'm pretty sure the problem is because you want your recursion to terminate when value == 1, and it's currently terminating when value == 0.
Your terminating expression is at issue. When value == 0 (or lower), it should return a 0 rather than 1. For sake of efficiency (which, let's admit it here, obviously isn't a concern, otherwise recursion wouldn't have been used for this task), you should terminate the recursion at value == 1 and return a literal 1 to save one unnecessary level of recursion.
using System;
using NUnit.Framework;
namespace Recursion
{
[TestFixture()]
public class Test
{
[Test()]
public void TestSum ()
{
Assert.AreEqual (Sum (new int[] { }), 0);
Assert.AreEqual (Sum (new int[] { 0 }), 0);
Assert.AreEqual (Sum (new int[] { 1 }), 1);
Assert.AreEqual (Sum (new int[] { 1, 2, 3, 4, 5 }), 15);
}
public int Sum(int[] head)
{
if (head.Length == 0) return 0;
int[] tail = new int[head.Length - 1];
for (int i = 1; i < head.Length; i++)
{
tail [i-1] = head [i];
}
return head[0] + Sum (tail);
}
}
}
It could also be written like this:
public static int sum(int n){
int total;
if(n==1){
total =1;
}else{
total = sum(n-1)+n;
}
return total;
}
Actually, I think you don't need to check case else because
public static int sum(int number){
if(number > 0){
return number + sum(--number);
}
return number; // return 0 so that's why you don't need check else condition
}
To begin at the end, a recursive Sum method looks like this:
// version 3
public static int Sum(int startRange, int endRange)
{
if (endRange > startRange)
{
return endRange + Sum(startRange, endRange - 1);
}
if (endRange < startRange)
{
return startRange + Sum(endRange, startRange - 1);
}
return endRange;
}
Hardcoding the startRange to be 0 gives us:
// version 2
public static int Sum(int range)
{
if (range > 0)
{
return range + Sum(0, range - 1);
}
if (range < 0)
{
return Sum(range, -1);
}
return range;
}
...and if you want to limit the method to positive numbers only, there's no need for a sign:
// version 1
public static unsigned int Sum(unsigned int range)
{
if (range > 0)
{
return range + Sum(0, range - 1);
}
return range;
}
I hope this helps give more of an insight into summing number ranges via recursion.
static int Sum(int[] addends)
{
if (addends.Length == 1)
{
return addends[0];
}
else
{
int tailIndex = addends.Length - 1;
var subArray = addends[0..tailIndex];
return addends[tailIndex] + Sum(subArray);
}
}
Try this code:
def sumr(n):
if n==0:
return n
return n+sumr(n-1)

Resources