Given an n-ary tree stored in a parent array, with the children stored in an array of pointers to arrays where the first value is the number of children:
(childArray[2][0] shows that node 2 has 2 children, childArray[2][1] shows that its first child is 5, etc.)
parentArray = {3, 0, 3, -1, 3, 2, 2};
childArray = {{1, 1}, {0}, {2, 5, 6}, {3, 0, 2, 4}, {0}, {0}, {0}};
produces a tree that looks like this:
3
/|\
0 2 4
| |\
1 5 6
Using a queue, how can I output the tree level by level like so:
Level 1: 3
Level 2: 0, 2, 4
Level 3: 1, 5, 6
Levels 1 and 2 are easy, because level 1 is just the root and level 2 is just its children, but after that I can't figure out how to get it to get the children of the children.
One way of doing so would be using a queue data structure.
Start with some queue q, and place in the index of the (unique) item whose parent is -1. Now, at each step, until q is empty,
Perform v <- pop(q) (popping the head)
Print out v
For each child w of v, do push(q, v) (pushing ot the tail)
For example, here are the first steps for your case:
Initially, q = [3] (3 is the index of the item whose parent is -1).
We pop q, print out 3, and push 0, 2, and 4, so q = [0, 2, 4].
Now we pop q, print out 0, and push 1, so q = [2, 4, 1].
Almost by definition, since q is popped from the front and added to the back, the nodes will be processed level by level.
The complexity is linear in the number of nodes.
You will have to perform a BFS (Breadth First Search) on the tree, while maintaining the number of nodes pushed into the next level. Outline:
q.push(root); nodesInCurrentLevel = 1; nodesInNextLevel = 0; currentLevelIndex = 1;
while q is not empty do:
u = q.pop()
print currentLevelIndex and u
decrement nodesInCurrentLevel
for every child v of u do:
increment nodesInNextLevel
q.push(v)
if nodesInCurrentLevel is 0 do:
nodesInCurrentLevel = nodesInNextLevel
nodesInNextLevel = 0
increment currentLevelIndex
Of course, this would print the output as Level 2:0 Level 2:2, etc. You can store current level nodes in a temporary list within the loop and print as appropriate.
Related
Given an integer n and array a, I need to find for each i, 1≤ i ≤ n, how many elements on the left are less than or equal to ai
Example:
5
1 2 1 1 2
Output
0 1 1 2 4
I can do it in O(N2) but I want to ask if there is any way to do it faster, since N is very large (N ≤ 106)?
You can use a segment tree, you just need to use a modified version called a range tree.
Range trees allow rectangle queries, so you can make the dimensions be index and value, and ask "What has value more than x, and index between 1 and n?"
Queries can be accomplished in O(log n) assuming certain common optimizations.
Either way O(N^2) is completely fine with N < 10^6.
I like to consider a bigger array to explain, so let's consider following array,
2, 1, 3, 4, 7, 6, 5, 8, 9, 10, 12, 0, 11, 13, 8, 9, 12, 20, 30, 60
The naïve way is to compare an element with all elements at left of it. Naïve approach has complexity of O(n^2) which make it not useful for big array.
If you look this problem closely you will find a pattern in it, and the pattern is Rather than comparing with each left element of an element we can compare first and last value of a range!. Wait a minute what is the range here?
These numbers can be viewed as ranges and there ranges can be created from traversing left to right in array. Ranges are as follows,
[2], [1, 3, 4, 7], [6], [5, 8, 9, 10, 12], [0, 11, 13], [8, 9, 12, 20, 30, 60]
Let’s start traversing array from left to right and see how we can create these ranges and how these ranges shall reduce the effort to find all small or equal elements at left of an element.
Index 0 have no element at its left to compare thus why we start form index 1, at this point we don’t have any range. Now we compare value of index 1 and index 0. Value 1 is not less than or equals to 2, so this is very import comparison, due to this comparison we know the previous range should end here because now numbers are not in acceding order and at this point we get first range [2], which contains only single element and number of elements less than or equals to left of element at index 1 is zero.
As continue with traversing left to right at index 2 we compare it with previous element which is at index 1 now value 1 <= 3 it means a new range is not staring here and we are still in same range which started at index 1. So to find how many elements less than or equals, we have to calculate first how many elements in current range [1, 3), in this case only one element and we have only one know range [2] at this point and it has one element which is less than 3 so total number of less than or equals elements at the left of element at index 2 is = 1 + 1 = 2. This can be done in similar way for rest of elements and I would like to jump directly at index 6 which is number 5,
At index 6, we have all ready discovered three ranges [2], [1, 3, 4, 7], [6] but only two ranges [2] and [1, 3, 4, 7] shall be considered. How I know in advance that range [6] is not useful without comparing will be explained at the end of this explanation. To find number of less than or equals elements at left, we can see first range [2] have only one element and it is less than 5, second range have first element 1 which is less than 5 but last element is 7 and it is greater than 5, so we cannot consider all elements of range rather we have to find upper bound in this range to find how many elements we can consider and upper bound can be found by binary search because range is sorted , so this range contains three elements 1, 3, 4 which are less then or equals to 5. Total number of elements less than or equals to 5 from two ranges is 4 and index 6 is first element of current range and there is no element at left of it in current range so total count = 1 + 3 + 0 = 4.
Last point on this explanation is, we have to store ranges in tree structure with their first value as key and value of the node should be array of pair of first and last index of range. I will use here std::map. This tree structure is required so that we can find all the range having first element less than or equals to our current element in logarithmic time by finding upper bound. That is the reason, I knew in advance when I was comparing element at index 6 that all three ranges known that time are not considerable and only two of them are considerable .
Complexity of solution is,
O(n) to travels from left to right in array, plus
O(n (m + log m)) for finding upper bound in std::map for each element and comparing last value of m ranges, here m is number of ranges know at particular time, plus
O(log q) for finding upper bound in a range if rage last element is greater than number, here q is number of element in particular range (It may or may not requires)
#include <iostream>
#include <map>
#include <vector>
#include <iterator>
#include <algorithm>
unsigned lessThanOrEqualCountFromRage(int num, const std::vector<int>& numList,
const std::map<int,
std::vector<std::pair<int, int>>>& rangeMap){
using const_iter = std::map<int, std::vector<std::pair<int, int>>>::const_iterator;
unsigned count = 0;
const_iter upperBoundIt = rangeMap.upper_bound(num);
for(const_iter it = rangeMap.cbegin(); upperBoundIt != it; ++it){
for(const std::pair<int, int>& range : it->second){
if(numList[range.second] <= num){
count += (range.second - range.first) + 1;
}
else{
auto rangeIt = numList.cbegin() + range.first;
count += std::upper_bound(rangeIt, numList.cbegin() +
range.second, num) - rangeIt;
}
}
}
return count;
}
std::vector<unsigned> lessThanOrEqualCount(const std::vector<int>& numList){
std::vector<unsigned> leftCountList;
leftCountList.reserve(numList.size());
leftCountList.push_back(0);
std::map<int, std::vector<std::pair<int, int>>> rangeMap;
std::vector<int>::const_iterator rangeFirstIt = numList.cbegin();
for(std::vector<int>::const_iterator it = rangeFirstIt + 1, endIt = numList.cend();
endIt != it;){
std::vector<int>::const_iterator preIt = rangeFirstIt;
while(endIt != it && *preIt <= *it){
leftCountList.push_back((it - rangeFirstIt) +
lessThanOrEqualCountFromRage(*it,
numList, rangeMap));
++preIt;
++it;
}
if(endIt != it){
int rangeFirstIndex = rangeFirstIt - numList.cbegin();
int rangeLastIndex = preIt - numList.cbegin();
std::map<int, std::vector<std::pair<int, int>>>::iterator rangeEntryIt =
rangeMap.find(*rangeFirstIt);
if(rangeMap.end() != rangeEntryIt){
rangeEntryIt->second.emplace_back(rangeFirstIndex, rangeLastIndex);
}
else{
rangeMap.emplace(*rangeFirstIt, std::vector<std::pair<int, int>>{
{rangeFirstIndex,rangeLastIndex}});
}
leftCountList.push_back(lessThanOrEqualCountFromRage(*it, numList,
rangeMap));
rangeFirstIt = it;
++it;
}
}
return leftCountList;
}
int main(int , char *[]){
std::vector<int> numList{2, 1, 3, 4, 7, 6, 5, 8, 9, 10, 12,
0, 11, 13, 8, 9, 12, 20, 30, 60};
std::vector<unsigned> countList = lessThanOrEqualCount(numList);
std::copy(countList.cbegin(), countList.cend(),
std::ostream_iterator<unsigned>(std::cout, ", "));
std::cout<< '\n';
}
Output:
0, 0, 2, 3, 4, 4, 4, 7, 8, 9, 10, 0, 11, 13, 9, 11, 15, 17, 18, 19,
Yes, It can be done in better time complexity compared to O(N^2) i.e O(NlogN). We can use the Divide and Conquer Algorithm and Tree concept.
want to see the source code of above mentioned two algorithms???
Visit Here .
I think O(N^2) should be the worst case. In this situation, we will have to traverse the array at least two times.
I have tried in O(N^2):
import java.io.*;
import java.lang.*;
public class GFG {
public static void main (String[] args) {
int a[]={1,2,1,1,2};
int i=0;
int count=0;
int b[]=new int[a.length];
for(i=0;i<a.length;i++)
{
for(int c=0;c<i;c++)
{
if(a[i]>=a[c])
{
count++;
}
}
b[i]=count;
count=0;
}
for(int j=0;j<b.length;j++)
System.out.print(b[j]+" ");
}`
I can't wrap my head around what's missing in my function to populate a binary tree vs the manual input.
Printing the head value along with its left & right node value doesn't seem to help me as well since it looks correct to me. However, printing out all the values after auto populating it produces a strange result.
The values of this binary tree will be coming from an array:
std::vector<ValueType> values = {
3,
7,4,
2,4,6,
8,5,9,3
};
Here is the tree relation:
3
(7,4)
7 4
(2,4) (4,6)
2 4 6
(8,5) (5,9) (9,3)
As you can see, the parent node is located above and its children is below enclosed in parenthesis.
row1: the root node 3 have left:7, right:4
row2: parent 7 have left:2, right:4
row2: parent 4 have left:4, right:6
...
This may seem not be a binary tree as mentioned from the comments, but look at it as a tree having null left or right node or a node having a shared children from its sibling (same row).
Below is the function to automatically populate the binary tree:
// ValueType is defined as an alias of int
void populateTree(BinaryTree* node, int rowCount, int lastIndex, std::vector<ValueType> values) {
for (int i = 0; i < rowCount; ++i) {
iterCount++;
int currentRow = (i * (i + 1)) / 2;
int x = i + 1;
int nextRow = (x * (x + 1)) / 2;
bool toggle = false;
for (int j = nextRow; j < nextRow + x; ++j) {
auto value = values[currentRow++];
node->value = node->parent != nullptr ? value : node->value;
if (j >= values.size())
continue;
auto leftValue = values[j + 0];
auto rightValue = values[j + 1];
node->left = new BinaryTree(node, leftValue);
node->right = new BinaryTree(node, rightValue);
if (j != currentRow)
std::cout << ", ";
std::cout << node->value << "(" << node->left->value << "," << node->right->value << ")";
node = toggle ? node->right : node->left;
toggle = !toggle;
}
std::cout << std::endl;
}
}
I have used the triangular number formula to map the array into row and column.
Now, to confirm if the code is working, starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom should be 23.
I've done this by traversing bottom-up and add all the adjacent node combinations. Here's the output of the result:
3(7,4)
7(2,4), 4(4,6)
2(8,5), 4(5,9), 6(9,3)
iter count: 14
============
[4, 4, 7, 3]:18
[5, 4, 2, 4, 7, 3]:25
[3, 6, 4, 2, 4, 7, 3]:29
[3, 6, 4, 2, 4, 7, 3]:29
[5, 2, 4, 7, 3]:21
[4, 7, 3]:14
[4, 3]:7
pair total sum: 54
There supposed to be a combinations of [n1, n2, n3, ...nX]:23.
However, if I build the binary tree manually, there is a correct combination:
3(7,4)
7(2,4), 4(4,6)
2(8,5), 4(5,9), 6(9,3)
iter count: 14
============
[8, 2, 7, 3]:20
[5, 2, 7, 3]:17
[5, 4, 7, 3]:19
[9, 4, 7, 3]:23 <--- this is the correct combination.
[5, 4, 4, 3]:16
[9, 4, 4, 3]:20
[9, 6, 4, 3]:22
[3, 6, 4, 3]:16
pair total sum: 83
Link to full source code: https://gist.github.com/mr5z/8249a9101e5bfdce4850602c3ea7ebf3
This is part of my solution to project euler#18
I’m not exactly sure about why your implement a tree structure an your own, but if your goal is visualisation of a certain tree structure: I would suggest you to use the boost cpp graph library in combination with graphiz
See an example here, which shows the construction of a family tree, in a more "graph orientated" way. Every graph (like a tree) has nodes and edges.
If you want to train your programming skills, please go ahead: I found the following example for a b-tree quite useful in my past.
Couldn’t you use a “normal” insertIntoTree function instead of you populateTree function ? Or is this a matter of performance for you ?
What you do here is an example of an XY problem (see here: Meta StackExchange: What is the XY problem? or there: GreyCat's Wiki: XyProblem) – you're trying to put your data into a tree structure just because they are presented in a way resembling a tree-like pyramid, but you did not check if such structure will actually help you solve the problem.
And the answer is: NO, it will not; it doesn't even fit the actual problem structure.
Your problem structure is a pyramid-like triangle of integer numbers, each of which has two nearest descendants (except those in the bottom row) and two nearest ancestors (except those on side edges, which have just one ancestor, and the top item, which has no ancestors at all). And you have already mapped that structure into a linear array by your 'triangular formula':
given a row number r in a range of 0 .. N-1 and a position in the row p in a range of 0 .. r and an array with indices 0 .. N*(N+1)/2-1,
the item (r,p) is stored in the array at index r*(r+1)/2 + p,
and its 'children' are (r+1,p) and (r+1,p+1).
That's all, the mapping allows you to access data in a 'triangular' manner, you need no tree to handle it.
Suppose I have two lists with elements that are natural numbers.
Set A has n elements and Set B starts with a single element.
Now could i code a program that takes a member from Set A, performs an operation
involving all the elements from Set B and then adds the element from set A to set B. Repeating this process until all elements from set A have been added to set B.
Example:
Set A = {3, 4, 5, 6} & Set B = {2}
Check to see if the first element from set A can be divided wholly by any element from set B. After this check has been done the first element from A goes to set B.
Set A = {4, 5, 6} & Set B = {2, 3}
Repeat
Set A = {5, 6} & Set B = { 2, 3, 4 }
Repeat
Set A = {6} & Set B = { 2, 3, 4, 5 }
Repeat
Set A = {} & Set B = { 2, 3, 4, 5, 6 }
END
RESOLVED
def getprime(n):
for p in range(2, n+1):
for i in range(2, p):
if p % i == 0:
break
else:
print(p)
This code solves your example question
Check to see if the first element from set A can be divided wholly by all elements from set B. After this check has been done the first element from A goes to set B.
I hope you can understand how to apply this to other similar questions.
A = [2, 4, 5, 6]
B = [2]
# while the list A is not empty
while len(A) > 0:
# the first number in the list
num = A[0]
# for every element in list B
for j in B:
fully_divisible = True
# the the number is not divisible by a number from list B
if num % j != 0:
fully_divisible = False
if fully_divisible:
# this will only print if ALL the numbers currently in list B are divisible by num
print num, "can be divided wholly by all elements from set B"
else:
# this will print if there is at least one number in list B the is not divisible by num
print num, "cannot be divided wholly by all elements from set B"
# remove the first element from list A, next time we loop the first element of the list (A[0]) will be different
A.remove(num)
# add that number to list B
B.append(num)
Output:
2 can be divided wholly by all elements from set B
4 can be divided wholly by all elements from set B
5 cannot be divided wholly by all elements from set B
6 cannot be divided wholly by all elements from set B
I have a set of lists that I want to compare firstly the sum values of the lists and then individual elements in the event of two or more lists having the same value.
my_list1 = [2, 3, 2, 4, 5]
my_list2 = [1, 3, 2, 3, 2]
my_list3 = [1, 1, 2, 2, 2]
my_list4 = [3, 2, 2, 4, 5]
Logic testing for an outright winner is fine but the problem I am having is isolating the lists in the event of a draw – So in the scenario above my_list1 and my_list4 would be isolated for further logic testing as their totals both come to 16.
This is what I have so far
my_list1=[1,1,2,2,2]
my_list2=[1,1,1,1,2]
my_list3=[2,2,1,1,2]
my_list1Total=sum(my_list1)
my_list2Total=sum(my_list2)
my_list3Total=sum(my_list3)
if my_list1Total>my_list2Total and my_list1Total>my_list3Total:
print("List one has the higest score")
elif my_list2Total>my_list1Total and my_list2Total>my_list3Total:
print("List two has the higest score")
elif my_list3Total>my_list2Total and my_list3Total>my_list1Total:
print("List three has the higest score")
else:
print("Draw")
##so now I want to compare the lists with the same total but this time by the first element in the list. In this case it would be my_list1[0] and my_list3[0] that would be compared next. The winner having the highest value in position 0 of the drawing lists
I suggest creating a single list which holds all of your lists. Then you can use max on that list to find the largest element. Or, if you want the index of the list and not just its value, you can write a max-like method and use that instead.
#like the built-in function `max`,
#but returns the index of the largest element
#instead of the largest element itself.
def index_of_max(seq, key=lambda item:item):
return max(range(len(seq)), key=lambda idx: key(seq[idx]))
lists = [
[2, 3, 2, 4, 5],
[1, 3, 2, 3, 2],
[1, 1, 2, 2, 2],
[3, 2, 2, 4, 5]
]
idx = index_of_max(lists, key=lambda item: (sum(item), item[0]))
#add one to this result because Python lists are zero indexed,
#but the original numbering scheme started at one.
print "List # {} is largest.".format(idx+1)
Result:
List # 4 is largest.
A little explanation about key: it's a function that you pass to max, that it uses to determine the comparative value of two items in the sequence. It calls key(someItem) on both items, and whichever item has a larger result, is considered the maximum item between the two of them. The key function I used here returns a tuple. Due to the way tuple comparison works in Python, comparison is done by sum first, then using the first element of each list as a tie breaker.
If you're thinking "but what if the first elements are also the same? I want to use each following item as a tie breaker", then you can modify the key to compare all of them in turn.
idx = index_of_max(lists, key=lambda item: [sum(item)]+item)
I am working with a finite element code, where the nodes of the mesh are distributed according to a map (let us call it single_mesh_nodes) with local and global identifier.
I need to make a new map (let us call it double_mesh_nodes) which should include the double number of nodes.
The double_mesh_nodes should be constructed taking as first part the single_mesh_nodes,
and afterwards starting again from the first node but assigning it new local and global identifiers. In other words, after the last global and local identifiers node (last_GID, and last_LID respectively) is reached, we should have again the first node but with a global identifier value of maximum GID +1, and a local identifier of maximum LID +1, and so on for the following nodes.
As an example, if we had a mesh of 4 nodes, with single_mesh_nodes LIDs = 0, 1, 2, 3, and GIDs = 0, 3, 2, 1, the double_mesh_nodes should have 4+4 nodes with LIDs = 0,1,2,3,4,5,6,7
and GIDs = 0, 3, 2, 1, 4, 7, 6, 5, that corresponds to the addition of the maximum GID number of the first 4 nodes to the single GIDs.