why putting loop above left and right function call is successfully submitting and when putting it below left and right function call is giving TLE - data-structures

I am working on the GeeksForGeeks code challenge K Sum Paths:
Given a binary tree and an integer K. Find the number of paths in the tree which have their sum equal to K.A path may start from any node and end at any node in the downward direction.
Input:
Tree =
1
/ \
3 -1
/ \ / \
2 1 4 5
/ / \ \
1 1 2 6
K = 5
Output: 8
Explanation:
The following paths sum to K.
3 2
3 1 1
1 3 1
4 1
1 -1 4 1
-1 4 2
5
1 -1 5
My first solution was this which was giving time limit exceeded.
class Solution {
int count = 0;
public int sumK(Node root,int k)
{
ArrayList<Integer> list = new ArrayList<>();
sum(root,k,list);
int ans = count;
return ans;
}
void sum(Node root, int k,ArrayList<Integer> list){
if( root == null) return;
list.add(root.data);
sum(root.left,k,list);
sum(root.right, k,list);
int sum = 0;
for(int i = list.size()-1;i>=0;i--){
sum+=list.get(i);
if(sum==k) count++;
}
list.remove(list.size()-1);
}
}
After putting the loop above the function calls it was successfully submitted. Why is that? Can anyone explain?.
class Solution {
int count = 0;
public int sumK(Node root,int k)
{
ArrayList<Integer> list = new ArrayList<>();
sum(root,k,list);
int ans = count;
return ans;
}
void sum(Node root, int k,ArrayList<Integer> list){
if( root == null) return;
list.add(root.data);
int sum = 0;
for(int i = list.size()-1;i>=0;i--){
sum+=list.get(i);
if(sum==k) count++;
}
sum(root.left,k,list);
sum(root.right, k,list);
list.remove(list.size()-1);
}
}

Related

How to convert the Post Order traversal stack implementation to a recursive version

This is an assignment related problem but in the requirement they did not ask for how it should be implemented. The input are represented as below:
Input:
5
4 1 2
2 3 4
5 -1 -1
1 -1 -1
3 -1 -1
4
/ \
2 5
/ \
1 3
Output:
1 3 2 5 4
where 5 is the number of total nodes and each row represents root, left and right node.
Here is my implementation of the PostOrder traversal, which is part of a bigger class:
private int n;
private int[] _key;
private int[] _left;
private int[] _right;
private List<int> PostOrder()
{
List<int> result = new List<int>(new int[n]);
int counter = n-1;
var stack = new Stack<int>();
stack.Push(0);
while (stack.Count > 0 && counter > 0)
{
int index = stack.Pop();
result[counter] = _key[index];
int leftIndex = _left[index];
int rightIndex = _right[index];
if (leftIndex != -1)
stack.Push(leftIndex);
if (rightIndex != -1)
stack.Push(rightIndex);
counter--;
}
return result;
}
I was trying to implement the recursive version of this implementation but stuck and can't show my progress. I know how the algorithm works in recursive manner:
PostOrder(root)
{
PostOrder(root.left);
PostOrder(root.right);
Visit/Print(root);
}
But not sure what would be argument or how should I return when the recursion hits the leaf, given that all the data are represented as arrays? Any help or suggestion is highly appreciated.
Try something like below:
private void PostOrder(result, index)
{
if (index == -1)
return;
int leftIndex = _left[index];
int rightIndex = _right[index];
PostOrder(result, leftIndex);
PostOrder(result, rightIndex);
//Add element in Post-Order
result.add(_key(index));
}
List<int> result = new List<int>();
PostOrder(result, 0);
//result will have the post-order sequence

Converging maze: Largest cycle

This question was asked in one interview and i am still hunting for the best solution.
You are given a maze with N cells. Each cell may have multiple entry points but not more than one exit
(ie. entry/exit points are unidirectional doors like valves).
The cells are named with an integer value from 0
to N-1.
You need to find the the length of the largest cycle in the maze. Return -1 if there are no cycles.
INPUT FORMAT
First line has the number of cells N
Second line has list of N values of the edge[] array. edge[i] contains the cell number that
can be reached from of cell ‘i’ in one step. edge[i] is -1 if the ‘i’th cell doesn’t have an exit.
OUTPUT FORMAT
length of the largest cycle.
Sample input:
23
4 4 1 4 13 8 8 8 0 8 14 9 15 11 -1 10 15 22 22 22 22 22 21
Sample output
6
I have already tried to do this with DFS to find all possible cycles and print the largest cycle size.
Please let me know if there is any better solution for the same.
Given a node in the graph, there's a unique maximal path starting from it (since there's at most one exit from any node). It may or may not cycle.
It's easy to find the eventual cycle length starting from a node: keep following exit nodes, recording nodes in a set along the path. Stop when you either find no exit node, or you're about to visit a previously visited node. If there's no exit node there's no cycle, and otherwise you can find the cycle length by starting at the previously visited node, and re-trace the cycle. [You could also use Floyd's algorithm here which would require O(1) rather than O(N) storage, but we're going to use O(N) storage anyway in the next step].
Using this, one can find the maximum cycle in O(N) time: repeat the above algorithm for each node in the graph, but cache results (storing -1 if there's no cycle found). You have to be careful to stop the cycle-finding above if you find a previously cached result along your path, and once you've found a result for a node, you must cache the result for all nodes along the path until you find a node who's result is already cached. The size of the largest cycle is the value of the largest cached value.
This is O(N) runtime: each edge (of which there's at most N) is followed at most 3 times in the graph, and the cache is updated exactly once for each node in the graph. It's uses O(N) additional storage.
public static int solution(int arr[])
{
ArrayList<Integer> sum = new ArrayList<>();
for(int i = 0; i < arr.length; i ++)
{
ArrayList<Integer> path = new ArrayList<>();
int j = i;
int tempSum = 0;
while(arr[j]<arr.length && arr[j]!=i && arr[j]!=-1 && !path.contains(j))
{
path.add(j);
tempSum+=j;
j=arr[j];
if(arr[j]==i)
{
tempSum+=j;
break;
}
}
if(j<arr.length && i == arr[j])
sum.add(tempSum);
}
if(sum.isEmpty())
return -1;
return Collections.max(sum);
}
Here is an implementation in JavaScript. I didn't use any fancy features of JavaScript, so the algorithm can be readily seen from the code. On the other hand, it does need ES6 support to run (forget IE):
function largestCycle(edges) {
var result, visitedFrom, startCell, cell, cells;
result = [];
visitedFrom = Array(edges.length).fill(-1);
for (startCell = 0; startCell < edges.length; startCell++) {
cells = [];
for (cell=startCell; cell>-1 && visitedFrom[cell]===-1; cell = edges[cell]) {
visitedFrom[cell] = startCell;
cells.push(cell);
}
if (cell > -1 && visitedFrom[cell] === startCell) {
cells = cells.slice(cells.indexOf(cell));
if (cells.length > result.length) result = cells;
}
}
return result;
}
// Snippet I/O
var input = document.querySelector('textarea');
var output = document.querySelector('span');
(input.oninput = function () {
// Get input as array of numbers
var edges = input.value.trim().split(/\s+/).map(Number);
// Apply algorithm
var cycle = largestCycle(edges);
// Output result
output.textContent = cycle.length + ': ' + JSON.stringify(cycle);
})(); // Execute also at page load
Input:<br>
<textarea style="width:100%">4 4 1 4 13 8 8 8 0 8 14 9 15 11 -1 10 15 22 22 22 22 22 21</textarea><br>
Greatest Cycle: <span></span>
This runs in O(n). Even though the outer loop has both a nested loop and an expression that iterates over an array (using slice and indexOf), these sub-iterations are only executed once per cell, so in total this is still O(n).
The function does not only return the cycle size, but also the array containing the list of cells that belong to that cycle. It is a small overhead, but allows to better verify the result.
Python implementation of the solution suggested by trincot.
Explanation:
iterate over each node
For each node use the indices to navigate to the next node. Eg(1st iteration : outer for loop)
from 0th index we can reach 4 , from 4th index we can reach 13 , and from 13th index we can reach 11, and so on till we reach the visited node again in our case 0,
viola , we have found the first cycle.
check if visitedFrom[cell] == startCell i.e. 0 add it to the result array.
repeat for next node (step1)
Code
def largestCycle(edges):
result = []
visitedFrom = [-1] * len(edges)
for startCell in range(0, len(edges)):
cells = []
cell = startCell
while cell > -1 and visitedFrom[cell] == -1:
visitedFrom[cell] = startCell
cells.append(cell)
cell = edges[cell]
if cell > -1 and visitedFrom[cell] == startCell:
cells_idx = cells.index(cell)
cells = cells[cells_idx:]
if len(cells) > len(result):
result = cells
return result,len(result)
size = 23
edges = [4, 4, 1, 4, 13, 8, 8, 8, 0, 8, 14, 9, 15, 11, -1, 10, 15, 22, 22, 22, 22, 22, 21]
largestCycle(edges)
Using Prims algorithm to Find max Cycle in the Node
n = int(input())
v = n
e = v+1
arr = [int(i) for i in input().split()]
graph = [[0 for _ in range(n)] for _ in range(n)]
for i in range(0, len(arr)):
graph[i][arr[i]] = 1
for i in graph:
print(i)
def min_ind(wieight, visied):
min_ = -1
ind = -1
for i in range(v):
if(wieight[i] > min_ and visied[i] == False):
min_ = wieight[i]
ind = i
return ind
def printPath(parent, i):
res = []
while(parent[i] != -1):
res.append(i)
i = parent[i]
res.append(i)
return res[::-1]
# Dijkstra
visited = [False for _ in range(v)]
wieight = [0 for _ in range(v)]
parent = [-1 for i in range(v)]
wieight[0] = 0
path = []
for _ in range(v):
u = min_ind(wieight, visited)
if(u == -1):
continue
visited[u] = True
for i in range(v):
if(graph[u][i] > 0 and visited[i] == False):
if(wieight[i] < graph[u][i]):
wieight[i] = graph[u][i]
parent[i] = u
maximum = 0
for i in range(0, len(wieight)):
print("No:", i, " Weight:", wieight[i], " Path:", end=" ")
path = (printPath(parent, i))
maximum = max(maximum, len(path))
print(path, end=" ")
print()
print("Longest Cycle: ", maximum)
here is the solution for the problem but input format is not actually the same.
Here is the input format:
test cases: N
size of array: M
array elements: 1<=a(i)<=M-1 where 0<=i<=M-1
index to which last index points: C
In this problem, we have to count the cells in the largest cycle, here is the code:
class countLargestCycleMaze {
static vertex[] cells;
static class vertex {
int name;
neighbor list;
public vertex(int v, neighbor nb) {
this.name = v;
this.list = nb;
}
}
static class neighbor {
int vnum;
neighbor next;
public neighbor(int v, neighbor nb) {
this.vnum = v;
this.next = nb;
}
}
static int dfs(int v, int m) {
neighbor tmp = cells[v].list;
int c = 0;
while (tmp.vnum != m)
tmp = cells[tmp.vnum].list;
tmp = cells[tmp.vnum].list;
while (tmp.vnum != m) {
tmp = cells[tmp.vnum].list;
c++;
}
return c;
}
public static void main(String[] args) throws java.lang.Exception {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int i, j, n, m, c;
n = Integer.parseInt(br.readLine());
while (n-- > 0) {
m = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
c = Integer.parseInt(br.readLine());
if (c == 0) {
System.out.println("0");
continue;
}
cells = new vertex[m + 1];
for (i = 0; i < m; i++) {
int num = Integer.parseInt(st.nextToken());
cells[i] = new vertex(num, null);
cells[i].list = new neighbor(num, cells[i].list);
}
cells[m] = new vertex(c, null);
cells[m].list = new neighbor(c, cells[m].list);
System.out.println(dfs(0, c));
}
} catch (Exception e) {}
}
}
public class LargestCycleInGraph {
public static int checkCycle(int []cell , int size , int start) {
Set<Integer> set = new HashSet<>();
set.add(start);
for(int i = start ;i< size;i++) {
if( !set.contains(cell[i]) && cell[i] != -1) {
set.add( cell[i] );
}
else return set.size() + 1; // 1 for again come to cycle node
}
return -1;
}
public static int findLargestCycle(int []cell , int size) {
int max = -1;
for(int i =0;i<size;i++) {
//if you want to find sum of largest cycle return "Set" rather than its size and check for max sum
int cyc = checkCycle(cell , size , i);
if(max < cyc)
max = cyc;
}
return max;
}
public static void main(String[] args) {
int size = 23;
int []cell = {4, 4, 1, 4, 13, 8, 8, 8, 0, 8, 14, 9, 15, 11, -1, 10, 15, 22, 22, 22, 22, 22, 21};
int largestCycle = findLargestCycle(cell , size);
System.out.println("Largest cycle Length " +largestCycle);
}
}
def main():
size = int(input())
cell = input().split()
for i in range(0, len(cell)):
cell[i] = int(cell[i])
m = -1
for i in range(0, 23):
if m < check_cycle(cell, i):
m = check_cycle(cell, i)
print("Largest cycle is made of", m, "nodes")
def check_cycle(cell, start):
i = start
if i in cell:
cycle = [i]
j = i
while 1:
for k in cycle:
if cycle.count(k) >= 2:
if cycle[0] == cycle[-1]:
return len(cycle)-1
else:
return 0
else:
cycle.append(cell[j])
j = cell[j]
else:
return 0
main()
Here is my attempt, to traverse each node of the graph:-
#include <stdio.h>
int findingLargestCycle(int noOfInputs, int *edges){
int largestCycle = 0;
for(int i=0; i<noOfInputs; i++){
int currentEdge = edges[i];
int count = currentEdge;
int nextEdge = edges[currentEdge];
int n = 0;
while(currentEdge != nextEdge && n<noOfInputs+1){
if(nextEdge == -1 || currentEdge == -1){
count = 0;
break;
}
if(nextEdge != currentEdge){
count += nextEdge;
}
nextEdge = edges[nextEdge];
n++;
}
if(count > largestCycle && n != noOfInputs+1){
largestCycle = count;
}
}
return largestCycle;
}
int main(){
int testCases;
scanf("%d", &testCases);
int numberOfInputs;
scanf("%d", &numberOfInputs);
int edges[numberOfInputs];
for(int i=0; i<numberOfInputs; i++){
scanf("%d", &edges[i]);
}
printf("%d", findingLargestCycle(numberOfInputs, &edges[0]));
}
O(n) time complexity solution each node is visited only after checking it's visited before or not, so each node is visited only once.
O(n) space complexity ([n]:stack space max + [2*n]:two map used max size)
To observe: there is always a unique path between two nodes(check with any test case), because of condition, only one exit from each node.
C++ code:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
//res stores result
int res = 0;
//visit to check in before visiting the node, to stop repeat visiting
unordered_map<int,bool> visit;
void dfs(vector<int> & a, unordered_map<int,int> &mp, int i, int k){
if(visit.find(i) != visit.end())
return;
if(a[i] == -1){
visit[i] = true;
return;
}
if(mp.find(i) != mp.end()){
res = max(res, k-mp[i]);
visit[i] = true;
return;
}
mp[i] = k;
dfs(a, mp, a[i], k+1);
visit[i] = true;
}
int main() {
int n;
cin>>n;
vector<int> a(n,0);
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++){
if(visit.find(i) == visit.end()){
unordered_map<int,int> mp;
dfs(a, mp, i, 0);
}
}
cout<<res<<endl;
return 0;
}
Solution in C++
#include <bits/stdc++.h>
using namespace std;
bool isCycle(vector<int> arr, int curr, vector<bool> &visited, vector<int> &path)
{
if (curr == -1)
{
return false;
}
if (visited[curr])
{
return true;
}
visited[curr] = true;
path.emplace_back(curr);
if (isCycle(arr, arr[curr], visited, path))
return true;
return false;
}
int largestSumCycle(vector<int> arr)
{
int n = arr.size();
int sum = INT_MIN;
vector<bool> visited(n, false);
for (int i = 0; i < n; i++)
{
visited[i] = true;
vector<int> path;
if (isCycle(arr, arr[i], visited, path))
sum = max(sum, accumulate(path.begin(), path.end(), 0));
visited[i] = false;
}
if (sum == INT_MIN)
return -1;
return sum;
}
This is a common question in interviews, in the same interview they asked this question also for the same details in question.
Q: find the NEAREST MEETING CELL (NMC)
INPUT : same as above + third line has 2 numbers whose nearest meeting cell is to be found.
SAMPLE INPUT
23
4 4 1 4 13 8 8 8 0 8 14 9 15 11 -1 10 15 22 22 22 22 22 21
9 2 (need to find out meeting point of 9 , 2 in the mesh/graph)
OUTPUT
4
CODE:
def main():
testCASES=int(input())
# testCASES=1
for case_number in range(testCASES):
meshsize=input()
mesh=input()
# mesh='4 4 1 4 13 8 8 8 0 8 14 9 15 11 -1 10 15 22 22 22 22 22 21'
det=input()
# det='9 2'
mesh=[int(x) for x in mesh.split()]
det=[int(x) for x in det.split()]
n1=det[0]
n2=det[1]
n1path=[]
n2path=[]
for i in range(len(mesh)):
if not n1path:
n1path.append(mesh[n1])
else:
n1path.append(mesh[n1path[i-1]])
if not n2path:
n2path.append(mesh[n2])
else:
n2path.append(mesh[n2path[i-1]])
nearestList=[]
try:
for x in n1path:
nearestList.append(n2path.index(x))
NEAREST_NODE=n2path[min(nearestList)]
except Exception as e:
NEAREST_NODE = -1
# print(n1path,n2path)
print(NEAREST_NODE)
main()
WORKING:
walks paths from given 2 points, and calculate first common point of n1path and n2path, by using min() function on indices of nearest list. naming is arbitary, but thats the core algo.
it can handle if cycles are present, and still return the first intersection point.
returns -1 if no matches are found.
This is one more variant of the problem, apart from the normal inpt, we're given two nodes, src and dest, and we have to output the node which is the closest to both src and dest.
Here's my solution to finding nearest cell from both src and dest
#include<bits/stdc++.h>
using namespace std;
//returns answer
int solution(vector<int> arr, int src, int dest){
// Two maps, visA for distance from src and visB for distance from dest
// They serve two purpose, if visA[x] == 0, that means we haven't reached that node yet,
// and if it holds any value, say d, that means it is d distance away from the particular node
map<int,int> visA,visB;
int start = arr[src];
int curr = 1;
set<int> s; // contains unique set of nodes to check at last
// iniitializing final nodes
for(auto &x: arr){
s.insert(x);
}
// traversing until we get to a cell where we've already reached
while(visA[start] == 0){
visA[start] = curr; // Marcking the distance
curr++;
start = arr[start];
if(start == -1){
break; // Getting out if we get to a node who is not pointing at any other node
}
}
start = arr[dest];
// Same logic as above but traversing from dest
while(visB[start] == 0){
visB[start] = curr;
curr++;
start = arr[start];
if(start == -1){
break;
}
}
// This is an array of two values, vp[i].first holds the sum of distance of vp[i].second from src and dest.
vector<pair<int,int>> vp;
for(auto &x: s){
if(visA[x] != 0 && visB[x] != 0){ // Checking if we ever got to that particular node from both src and dest or not
pair<int,int> p = {visA[x] + visB[x], x};
vp.push_back(p);
}
}
// sorting and finding the node with list sum of visA[} + visB[]
sort(vp.begin(), vp.end());
return vp[0].second;
}
int main(){
int n; cin>>n;
vector<int> v;
for(int i = 0; i<n; i++){
int a; cin>>a;
v.push_back(a);
}
int a,b; cin>>a>>b;
cout << (solution(v,a,b));
}
function largestCycle(edges) {
var result, visitedFrom, startCell, cell, cells;
result = [];
visitedFrom = Array(edges.length).fill(-1);
for (startCell = 0; startCell < edges.length; startCell++) {
cells = [];
for (cell=startCell; cell>-1 && visitedFrom[cell]===-1; cell = edges[cell]) {
visitedFrom[cell] = startCell;
cells.push(cell);
}
if (cell > -1 && visitedFrom[cell] === startCell) {
cells = cells.slice(cells.indexOf(cell));
if (cells.length > result.length) result = cells;
}
}
return result;
}
// Snippet I/O
var input = document.querySelector('textarea');
var output = document.querySelector('span');
(input.oninput = function () {
// Get input as array of numbers
var edges = input.value.trim().split(/\s+/).map(Number);
// Apply algorithm
var cycle = largestCycle(edges);
// Output result
output.textContent = cycle.length + ': ' + JSON.stringify(cycle);
})(); // Execute also at page load
Input:<br>
<textarea style="width:100%">4 4 1 4 13 8 8 8 0 8 14 9 15 11 -1 10 15 22 22 22 22 22 21</textarea><br>
Greatest Cycle: <span></span>

Print ways to reach the n’th stair

I recently encountered this problem in an interview
There are n stairs, a person standing at the bottom wants to reach the top. The person can climb either 1 stair or 2 stairs at a time.
Print all possible ways person can reach the top.
For example, n=4 Output:
1 2 3 4
1 2 4
1 3 4
2 3 4
2 4
But I couldn't code this properly. How to code up solution for this?
To print the number of ways, you can first understand how to calculate the number of ways, and adjust it so each "count" will print instead of just count:
D(0) = 1
D(-1) = 0
D(i) = D(i-1) + D(i-2)
To adjust it to actual printing, you need to "remember" the choices you have made, and follow the same logic. Pseudo code:
printWays(curr, n, soFar):
if curr > n:
return
soFar.append(curr)
if n == curr:
print soFar
soFar.removeLast()
return
printWays(curr+1,n,soFar)
printWays(curr+2,n,soFar)
soFar.removeLast()
The idea is:
soFar is the current series of steps you did.
curr is the current step you're at.
n is the last stair you need to get to.
At each point, you either climb one stair or two. You check both options.
You can try some recursive solution where you call recursively CanClimb(n-1) and CanClimb(n-2) to visualize the possible ways.
Sample solution in C#:
public static void ClimbWays(int n, int currentIndex, int[] currectClimb)
{
if (n < 0) return;
if (n == 0)
{
for (var i = currentIndex - 1; i >= 0; i--)
{
Console.Write(currectClimb[i] + " ");
}
Console.WriteLine();
return;
}
currectClimb[currentIndex] = n;
ClimbWays(n - 1, currentIndex + 1, currectClimb);
ClimbWays(n - 2, currentIndex + 1, currectClimb);
}
Output for ClimbWays(4, 0, new int[4]);:
1 2 3 4
2 3 4
1 3 4
1 2 4
2 4
If you want to just count them you can use the well known Fibonacci sequence which can be calculated iteratively:
public static int Fibonacci(int n)
{
int a = 0;
int b = 1;
// In N steps compute Fibonacci sequence iteratively.
for (int i = 0; i < n; i++)
{
int temp = a;
a = b;
b = temp + b;
}
return a;
}

maximum sum of value from root to leaf in a binary tree using stack

I am trying to find the maximum sum of value from root to leaf nodes in a binary tree using stack.
I wrote the following code but there is a bug in it .
<>
Stacks s;
s.push(root);
maxSum=currSum=0;
while(!s.isEmpty()) {
temp = s.top();
s.pop();
if( temp->left == null && temp->right == null ) {
currSum = currSum+temp->data;
if(currSum > maxSum) {
maxSum = currSum;
}
currSum =0;
} else {
currSum = currSum + temp->data;
if(temp->left) s.push(temp->left);
if(temp->right) s.push(temp->right);
}
}
What I am trying to do is calculate the sum till the leaf node and assign it to maxSum.
Ex:- Binary tree is
1
/ \
2 3
/ \
4 5
1)I first push 1 and pop . currSum =1;
2) Push 3 and 2 and pop 2. cursum = 3 and push 5 and 4;
3) Stack now looks like 4<-5-<3-<1 (4 is top element)
4)Now as 4 is leaf node , I enter the if loop and add currSum = 3+4=7 and pop 4 .
5)Now temp is 5 and I set currSum=0, so currSum when I pop 5 becomes 5 .
Can anyone help me fix this bug please
10
/ \
8 2
Consider this example for your code.
First root(10) is pushed into the stack and immediately we are popping it.
Now the currsum becomes 10 and left (8) and right (2) nodes are pushed into the stack.
Now topmost element(2) is popped and added to currsum.Now currsum becomes 12.
As we reached leaf node, maxsum contains currsum value.
And currsum is made 0.
This is a mistake as we are losing the root value.
Now we pop the last element (8) and the currsum has value 8.As we reached leaf node,we compare with maxsum(12) and the final answer is
12 which is wrong.
The Code below will help you through. Try using stack in place of vector.
using namespace std;
struct node {
int data;
struct node* left;
struct node* right;
};
struct node* createNode(int k) {
struct node* temp = new node;
temp->left = NULL;
temp->right = NULL;
temp->data = k;
return temp;
}
int tsum(vector<struct node *> path) {
int sum;
int n = path.size();
int i;
for (i = 0; i < n; i++)
sum = sum + path[i]->data;
return sum;
}
int maxsum(struct node *root) {
int currsum = 0, maxsum = 0;
vector<struct node *> v;
v.push_back(root); //Push root
vector<int> visited(100, 0);
while (v.size() > 0) {
visited[v.back()->data] = 1; //whenever node is reached mark visited
if (v.back()->left != NULL && !visited[v.back()->left->data])
v.push_back(v.back()->left);
else if (v.back()->right != NULL && !visited[v.back()->right->data])
v.push_back(v.back()->right);
else {
if (!v.back()->left && !v.back()->right) {
currsum = tsum(v);
if (currsum > maxsum)
maxsum = currsum;
}
v.pop_back(); //pop here is used for backtracking
}
}
return maxsum;
}
int main() {
int sum = 0;
std::vector<int> arr;
/* Constructed binary node is
1
/ \
2 3
/ \
4 5
*/
struct node *root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
int s = 0;
s = maxsum(root);
cout << "SUM" << s << "\n";
return 0;
}

Retrieving the Min element in a stack in O(1) Time

The reason I'm asking this question is because I cannot see why the way I think cannot be applied to this particular question
"How would you design a stack which,
in addition to push and pop, also has a function min which returns the minimum element? Push, pop and min should all operate in O(1) time"
My basic solution: Wouldn't it be possible if we had a variable in stack class, that whenever we were pushing an item to stack we would check if it is smaller than our min variable. If it is assign the value to the min, if not ignore.
You would still get the O(1) as the min function would be;
int getMinimum(){
return min;
}
Why this solution is never mentioned, or what is the fault with the way I think?
This wouldn't work if you popped numbers off the stack.
Ex. 2,4,5,3,1. After you pop 1 off, what is your minimum?
The solution is to keep a stack of minimums, not just a single value. If you encounter a value that is less than equal to the current minimum, you need to push it onto the min-stack.
Ex.
Push(4):
Stack: 4
Min-stack: 4
Push(2):
Stack: 4 2
Min-stack: 4 2
Push(2):
Stack: 4 2 2
Min-stack: 4 2 2
Push(5):
Stack: 4 2 2 5
Min-stack: 4 2 2
Push(3):
Stack: 4 2 2 5 3
Min-stack: 4 2 2
Push(1):
Stack: 4 2 2 5 3 1
Min-stack: 4 2 2 1
Pop():
Stack: 4 2 2 5 3
Min-stack: 4 2 2
Pop():
Stack: 4 2 2 5
Min-stack: 4 2 2
Pop():
Stack: 4 2 2
Min-stack: 4 2 2
Pop():
Stack: 4 2
Min-stack: 4 2
Pop():
Stack: 4
Min-stack: 4
Use a linked list to keep track of the minimum value which is gonna be the head.
Note that linkedlist.app= append ( we put the value in the tail ).
linkedlist.pre =prepend ( we put the value as the head of the linkedlist)
public class Stack {
int[] elements;
int top;
Linkedlists min;
public Stack(int n) {
elements = new int[n];
top = 0;
min = new Linkedlists();
}
public void realloc(int n) {
int[] tab = new int[n];
for (int i = 0; i < top; i++) {
tab[i] = elements[i];
}
elements = tab;
}
public void push(int x) {
if (top == elements.length) {
realloc(elements.length * 2);
}
if (top == 0) {
min.pre(x);
} else if (x < min.head.data) {
min.pre(x);
} else {
min.app(x);
}
elements[top++] = x;
}
public int pop() {
int x = elements[--top];
if (top == 0) {
}
if (this.getMin() == x) {
min.head = min.head.next;
}
elements[top] = 0;
if (4 * top < elements.length) {
realloc((elements.length + 1) / 2);
}
return x;
}
public void display() {
for (Object x : elements) {
System.out.print(x + " ");
}
}
public int getMin() {
if (top == 0) {
return 0;
}
return this.min.head.data;
}
public static void main(String[] args) {
Stack stack = new Stack(4);
stack.push(2);
stack.push(3);
stack.push(1);
stack.push(4);
stack.push(5);
stack.pop();
stack.pop();
stack.pop();
stack.push(1);
stack.pop();
stack.pop();
stack.pop();
stack.push(2);
System.out.println(stack.getMin());
stack.display();
}
}
I found this solution here
struct StackGetMin {
void push(int x) {
elements.push(x);
if (minStack.empty() || x <= minStack.top())
minStack.push(x);
}
bool pop() {
if (elements.empty()) return false;
if (elements.top() == minStack.top())
minStack.pop();
elements.pop();
return true;
}
bool getMin(int &min) {
if (minStack.empty()) {
return false;
} else {
min = minStack.top();
return true;
}
}
stack<int> elements;
stack<int> minStack;
};

Resources