Suppose I have an array: list1 = [8, 5, 3, 1, 1, 10, 15, 9]
Now if the element is less than its previous element, increase it till the previous element with one.
Here:
5 < 8 so 5 should become: 5 + 3 + 1 = 9 i.e (8+1)
3 < 5 so 3 should become: 3 + 2 + 1 = 6 i.e (5+1)
1 < 3 so 1 should become: 1 + 2 + 1 = 4 i.e (3+1)
Now I am able to get the difference between elements if its less than its previous element.
But, how to use it in a final list to get an output like this:
finallist = [8, 9, 6, 4, 1, 10, 15, 16]
Also how can I get a final list value of 'k' list in my code? Right now it shows:
[2]
[2, 4]
[2, 4, 3]
[2, 4, 3, 3]
[2, 4, 3, 3, 7]
Source code:
list1 = [8, 5, 3, 1, 1, 10, 15, 9]
k = []
def comput(x):
if i[x] < i[x-1]:
num = (i[x-1] - i[x]) + 1
k.append(num)
print(k)
return
for i in [list1]:
for j in range(len(list1)):
comput(j)
You can use a list comprehension for this. Basically, the following code will check if one is larger than the next. If it is, then it will convert it to the previous+1.
list1 = [8, 5, 3, 1, 1, 10, 15, 9]
k = [list1[0]] + [i if j<=i else j+1 for i,j in zip(list1[1:],list1[:-1])]
cost = [j-i for i,j in zip(list1,k)]
print(k)
print(cost)
Output:
[8, 9, 6, 4, 1, 10, 15, 16]
[0, 4, 3, 3, 0, 0, 0, 7]
The following code will create a new list with the required output
l1 = [8, 5, 3, 1, 1, 10, 15, 9]
l = [l1[0]]
c=[0] # cost / difference list
for i in range(len(l1)-1):
if l1[i+1] < l1[i]:
l.append(l1[i]+1)
c.append(l1[i]+1-l1[i+1])
else:
l.append(l1[i+1])
c.append(0)
print(l)
Output
[8, 9, 6, 4, 1, 10, 15, 16]
[0, 4, 3, 3, 0, 0, 0, 7]
I want to find sum of arrays from 1 to 100.Each number is converted to array containing its own digits eg 97 will be [9,7].Here is what i have tried
(1..100).to_a.each do |i|
i.to_s.split("").map(&:to_i).inject(0) { |sum, number| sum + number }
end
But the sum of arrays are not displayed correctly!
For example;We first create an array of the digits and then return sum
[1]=1
[5]=5
[1, 0]=1
[1, 1]=2
[1, 2]=3
[1, 3]=4
[1, 4]=5
So sum of individual arrays is to be returned.
each will iterate the array, but not create a new array with the result of the block. If you want the results at the end, you need to use map:
result = (1..100).to_a.map do |i|
i.to_s.split("").map(&:to_i).inject(0) { |sum, number| sum + number }
end
result
#=> [1, 2, 3, 4, ...]
For summing an array you can also simply write
array.inject(:+)
# instead of
array.inject(0) { |sum, number| sum + number }
Also, the to_a is not necessary, you can directly call each and/or map on a range. So the simplified code would be
result = (1..100).map do |i|
i.to_s.split("").map(&:to_i).inject(:+)
end
result
#=> [1, 2, 3, 4, ...]
For your codes, you just need to change each method to map.
(1..100).to_a.map do |i|
i.to_s.split("").map(&:to_i).inject(0) { |sum, number| sum + number }
end
more simplicity way:
result = (1..100).to_a.map{ |e| e.to_s.split('').map(&:to_i).reduce(:+) }
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1]
if you want to get the sum of result, just do like this:
result.reduce(:+)
If I understand your question correctly you want the sum of these new arrays, right? This should solve your problem:
(1..100).map { |i| i.to_s.split("").map(&:to_i).inject(:+) }.inject(:+)
digits and sum are newer methods, simplifying this to
(1..100).sum{|i| i.digits.sum}
Another alternative for modern newer versions of Ruby:
(1..100).flat_map(&:digits).sum
Given a BST, find all sequences of nodes starting from root that will essentially give the same binary search tree.
Given a bst, say
3
/ \
1 5
the answer should be 3,1,5 and 3,5,1.
another example
5
/ \
4 7
/ / \
1 6 10
the outputs will be
5,4,1,7,6,10
5,4,7,6,10,1
5,7,6,10,4,1
etc
The invariant here however is that the parent's index must always be lesser than its children. I am having difficulty implementing it.
I assume you want a list of all sequences which will generate the same BST.
In this answer, we will use Divide and Conquer. We will create a function findAllSequences(Node *ptr) which takes a node pointer as input and returns all the distinct sequences which will generate the subtree hanging from ptr. This function will return a Vector of Vector of int, i.e. vector<vector<int>> containing all the sequences.
The main idea for generating sequence is that root must come before all its children.
Algorithm:
Base Case 1:
If ptr is NULL, then return a vector with an empty sequence.
if (ptr == NULL) {
vector<int> seq;
vector<vector<int> > v;
v.push_back(seq);
return v;
}
Base Case 2:
If ptr is a leaf node, then return a vector with a single sequence. Its Trivial that this sequence will contain only a single element, i.e. value of that node.
if (ptr -> left == NULL && ptr -> right == NULL) {
vector<int> seq;
seq.push_back(ptr -> val);
vector<vector<int> > v;
v.push_back(seq);
return v;
}
Divide Part (this part is very simple.)
We assume that we have a function that can solve this problem, and thus we solve it for left sub tree and right sub tree.
vector<vector<int> > leftSeq = findAllSeq(ptr -> left);
vector<vector<int> > rightSeq = findAllSeq(ptr -> right);
Merging the two solutions.(The crux is in this step.)
Till now we have two set containg distinct sequences:
i. leftSeq - all sequences in this set will generate left subtree.
ii. rightSeq - all sequences in this set will generate right subtree.
Now each sequence in left subtree can be merged with each sequence of right subtree. While merging we should be careful that the relative order of elements is preserved. Also in each of the merged sequence we will add the value of current node in the beginning beacuse root must come before all children.
Pseudocode for Merge
vector<vector<int> > results
for all sequences L in leftSeq
for all sequences R in rightSeq
create a vector flags with l.size() 0's and R.size() 1's
for all permutations of flag
generate the corresponding merged sequence.
append the current node's value in beginning
add this sequence to the results.
return results.
Explanation: Let us take a sequence, say L(of size n) from the set leftSeq, and a sequence, say R(of size m) from set rightSeq.
Now these two sequences can be merged in m+nCn ways!
Proof: After merging, the new sequence will have m + n elements. As we have to maintain the relative order of elements, so firstly we will fill all n the elements from L in any of n places among total (m+n) places. After that remaining m places can be filled by elements of R. Thus we have to choose n places from (m+n) places.
To do this, lets create take a Boolean vector, say flags and fill it with n 0's and m 1's.A value of 0 represents a member from left sequence and a value of 1 represents member from right sequence. All what is left is to generate all permutations of this flags vector, which can be done with next_permutation. Now for each permutation of flags we will have a distinct merged sequence of L and R.
eg: Say L={1, 2, 3} R={4, 5}
so, n=3 and m=2
thus, we can have 3+2C3 merged sequences, i.e. 10.
1.now, Initially flags = {0 0 0 1 1}, filled with 3 0's and 2 1's
this will result into this merged sequence: 1 2 3 4 5
2.after calling nextPermutation we will have
flags = {0 0 1 0 1}
and this will generate sequence: 1 2 4 3 5
3.again after calling nextPermutation we will have
flags = {0 0 1 1 0}
ans this will generate sequence: 1 2 4 5 3and so on...
Code in C++
vector<vector<int> > findAllSeq(TreeNode *ptr)
{
if (ptr == NULL) {
vector<int> seq;
vector<vector<int> > v;
v.push_back(seq);
return v;
}
if (ptr -> left == NULL && ptr -> right == NULL) {
vector<int> seq;
seq.push_back(ptr -> val);
vector<vector<int> > v;
v.push_back(seq);
return v;
}
vector<vector<int> > results, left, right;
left = findAllSeq(ptr -> left);
right = findAllSeq(ptr -> right);
int size = left[0].size() + right[0].size() + 1;
vector<bool> flags(left[0].size(), 0);
for (int k = 0; k < right[0].size(); k++)
flags.push_back(1);
for (int i = 0; i < left.size(); i++) {
for (int j = 0; j < right.size(); j++) {
do {
vector<int> tmp(size);
tmp[0] = ptr -> val;
int l = 0, r = 0;
for (int k = 0; k < flags.size(); k++) {
tmp[k+1] = (flags[k]) ? right[j][r++] : left[i][l++];
}
results.push_back(tmp);
} while (next_permutation(flags.begin(), flags.end()));
}
}
return results;
}
Update 3rd March 2017: This solution wont work perfectly if original tree contains duplicates.
Here is a clear, concise and well-documented solution that I wrote for you in Python 3. I hope it helps you!
Code: bst_sequences.py
from binarytree import bst, Node
def weave_lists(first: list, second: list, results: list, prefix: list) -> None:
"""Recursively Weave the first list into the second list and append
it to the results list. The prefix list grows by an element with the
depth of the call stack. Ultimately, either the first or second list will
be exhausted and the base case will append a result."""
# base case
if not first or not second:
results.append(prefix + first + second)
return
# recursive case
first_head, first_tail = first[0], first[1:]
weave_lists(first_tail, second, results, prefix + [first_head])
second_head, second_tail = second[0], second[1:]
weave_lists(first, second_tail, results, prefix + [second_head])
def all_sequences(root: Node) -> list:
"""Splits the tree into three lists: prefix, left, and right."""
if root is None:
return []
answer = []
prefix = [root.value]
left = all_sequences(root.left) or [[]]
right = all_sequences(root.right) or [[]]
# At a minimum, left and right must be a list containing an empty list
# for the following nested loop
for i in range(len(left)):
for j in range(len(right)):
weaved = []
weave_lists(left[i], right[j], weaved, prefix)
answer.extend(weaved)
return answer
if __name__ == "__main__":
t = bst(2)
print(t)
solution = all_sequences(t)
for e, item in enumerate(solution):
print(f"{e:03}: {item}")
Sample Output
__4
/ \
1 5
/ \ \
0 2 6
000: [4, 1, 0, 2, 5, 6]
001: [4, 1, 0, 5, 2, 6]
002: [4, 1, 0, 5, 6, 2]
003: [4, 1, 5, 0, 2, 6]
004: [4, 1, 5, 0, 6, 2]
005: [4, 1, 5, 6, 0, 2]
006: [4, 5, 1, 0, 2, 6]
007: [4, 5, 1, 0, 6, 2]
008: [4, 5, 1, 6, 0, 2]
009: [4, 5, 6, 1, 0, 2]
010: [4, 1, 2, 0, 5, 6]
011: [4, 1, 2, 5, 0, 6]
012: [4, 1, 2, 5, 6, 0]
013: [4, 1, 5, 2, 0, 6]
014: [4, 1, 5, 2, 6, 0]
015: [4, 1, 5, 6, 2, 0]
016: [4, 5, 1, 2, 0, 6]
017: [4, 5, 1, 2, 6, 0]
018: [4, 5, 1, 6, 2, 0]
019: [4, 5, 6, 1, 2, 0]
Process finished with exit code 0
I have a much shorter solution. What do you think about it?
function printSequences(root){
let combinations = [];
function helper(node, comb, others){
comb.push(node.values);
if(node.left) others.push(node.left);
if(node.right) others.push(node.right);
if(others.length === 0){
combinations.push(comb);
return;
}else{
for(let i = 0; i<others.length; i++){
helper(others[i], comb.slice(0), others.slice(0, i).concat(others.slice(i+1, others.length)));
}
}
}
helper(root, [], []);
return combinations;
}
Note that the question is actually about topological sorting of a tree: find all the possible ways to perform topological sort. That is, we don't care about the specific way the tree was built, what's important is that elements are always added as leaves, never changing the structure of existing nodes. The constraint on the output is that nodes never precede their ancestors - treating the tree as a classic dependency graph.
But unlike topological sort for a general DAG, there's no need for reference counting here, since this is a tree - the number of references is always 1 or 0.
Here's a simple Python implementation:
def all_toposorts_tree(sources, history):
if not sources:
print(history)
return
for t in sources:
all_toposorts((sources - {t}) | {t.left, t.right} - {None}, history + [t.v])
all_toposorts_tree({root}, [])
This is question 4.9 in Cracking the Coding Interview, 6th Edition.
well here is my python code which does producing all sequences of elements/numbers for same BST.
for the logic i referred to the book cracking the coding interview by Gayle Laakmann Mcdowell
from binarytree import Node, bst, pprint
def wavelist_list(first, second, wave, prefix):
if first:
fl = len(first)
else:
fl = 0
if second:
sl = len(second)
else:
sl = 0
if fl == 0 or sl == 0:
tmp = list()
tmp.extend(prefix)
if first:
tmp.extend(first)
if second:
tmp.extend(second)
wave.append(tmp)
return
if fl:
fitem = first.pop(0)
prefix.append(fitem)
wavelist_list(first, second, wave, prefix)
prefix.pop()
first.insert(0, fitem)
if sl:
fitem = second.pop(0)
prefix.append(fitem)
wavelist_list(first, second, wave, prefix)
prefix.pop()
second.insert(0, fitem)
def allsequences(root):
result = list()
if root == None:
return result
prefix = list()
prefix.append(root.value)
leftseq = allsequences(root.left)
rightseq = allsequences(root.right)
lseq = len(leftseq)
rseq = len(rightseq)
if lseq and rseq:
for i in range(lseq):
for j in range(rseq):
wave = list()
wavelist_list(leftseq[i], rightseq[j], wave, prefix)
for k in range(len(wave)):
result.append(wave[k])
elif lseq:
for i in range(lseq):
wave = list()
wavelist_list(leftseq[i], None, wave, prefix)
for k in range(len(wave)):
result.append(wave[k])
elif rseq:
for j in range(rseq):
wave = list()
wavelist_list(None, rightseq[j], wave, prefix)
for k in range(len(wave)):
result.append(wave[k])
else:
result.append(prefix)
return result
if __name__=="__main__":
n = int(input("what is height of tree?"))
my_bst = bst(n)
pprint(my_bst)
seq = allsequences(my_bst)
print("All sequences")
for i in range(len(seq)):
print("set %d = " %(i+1), end="")
print(seq[i])
example output:
what is height of tree?3
___12
/ \
__ 6 13
/ \ \
0 11 14
\
2
All sequences
set 1 = [12, 6, 0, 2, 11, 13, 14]
set 2 = [12, 6, 0, 2, 13, 11, 14]
set 3 = [12, 6, 0, 2, 13, 14, 11]
set 4 = [12, 6, 0, 13, 2, 11, 14]
set 5 = [12, 6, 0, 13, 2, 14, 11]
set 6 = [12, 6, 0, 13, 14, 2, 11]
set 7 = [12, 6, 13, 0, 2, 11, 14]
set 8 = [12, 6, 13, 0, 2, 14, 11]
set 9 = [12, 6, 13, 0, 14, 2, 11]
set 10 = [12, 6, 13, 14, 0, 2, 11]
set 11 = [12, 13, 6, 0, 2, 11, 14]
set 12 = [12, 13, 6, 0, 2, 14, 11]
set 13 = [12, 13, 6, 0, 14, 2, 11]
set 14 = [12, 13, 6, 14, 0, 2, 11]
set 15 = [12, 13, 14, 6, 0, 2, 11]
set 16 = [12, 6, 0, 11, 2, 13, 14]
set 17 = [12, 6, 0, 11, 13, 2, 14]
set 18 = [12, 6, 0, 11, 13, 14, 2]
set 19 = [12, 6, 0, 13, 11, 2, 14]
set 20 = [12, 6, 0, 13, 11, 14, 2]
set 21 = [12, 6, 0, 13, 14, 11, 2]
set 22 = [12, 6, 13, 0, 11, 2, 14]
set 23 = [12, 6, 13, 0, 11, 14, 2]
set 24 = [12, 6, 13, 0, 14, 11, 2]
set 25 = [12, 6, 13, 14, 0, 11, 2]
set 26 = [12, 13, 6, 0, 11, 2, 14]
set 27 = [12, 13, 6, 0, 11, 14, 2]
set 28 = [12, 13, 6, 0, 14, 11, 2]
set 29 = [12, 13, 6, 14, 0, 11, 2]
set 30 = [12, 13, 14, 6, 0, 11, 2]
set 31 = [12, 6, 11, 0, 2, 13, 14]
set 32 = [12, 6, 11, 0, 13, 2, 14]
set 33 = [12, 6, 11, 0, 13, 14, 2]
set 34 = [12, 6, 11, 13, 0, 2, 14]
set 35 = [12, 6, 11, 13, 0, 14, 2]
set 36 = [12, 6, 11, 13, 14, 0, 2]
set 37 = [12, 6, 13, 11, 0, 2, 14]
set 38 = [12, 6, 13, 11, 0, 14, 2]
set 39 = [12, 6, 13, 11, 14, 0, 2]
set 40 = [12, 6, 13, 14, 11, 0, 2]
set 41 = [12, 13, 6, 11, 0, 2, 14]
set 42 = [12, 13, 6, 11, 0, 14, 2]
set 43 = [12, 13, 6, 11, 14, 0, 2]
set 44 = [12, 13, 6, 14, 11, 0, 2]
set 45 = [12, 13, 14, 6, 11, 0, 2]
here is another concise recursion based easy to understand solution:
from binarytree import Node, bst, pprint
def allsequences1(root):
if not root:
return None
lt = allsequences1(root.left)
rt = allsequences1(root.right)
ret = []
if not lt and not rt:
ret.append([root])
elif not rt:
for one in lt:
ret.append([root]+one)
elif not lt:
for two in rt:
ret.append([root]+two)
else:
for one in lt:
for two in rt:
ret.append([root]+one+two)
ret.append([root]+two+one)
return ret
if __name__=="__main__":
n = int(input("what is height of tree?"))
my_bst = bst(n)
pprint(my_bst)
seg = allsequences1(my_bst)
print("All sequences ..1")
for i in range(len(seq)):
print("set %d = " %(i+1), end="")
print(seq[i])
Let's first observe what must be be followed to create the same BST. The only sufficient rules here is insert parent before their left and right children. Because, if we can guarantee that for some node (that we are interested to insert) all parents (including grand parent) are inserted but none of it's children are inserted, than the node will find its appropriate place to be inserted.
Following this observation we can write backtrack to generate all sequence that will produce same BST.
active_list = {root}
current_order = {}
result ={{}}
backtrack():
if(len(current_order) == total_node):
result.push(current_order)
return;
for(node in active_list):
current_order.push(node.value)
if node.left :
active_list.push(node.left)
if node.right:
active_list.push(node.right)
active_list.remove(node)
backtrack()
active_list.push(node)
if node.left :
active_list.remove(node.left)
if node.right:
active_list.remove(node.right)
current_order.remove(node.val)
This is not working implementation. used just for illustration purpose.
public class Solution {
ArrayList<LinkedList<Long>> result;
/*Return the children of a node */
ArrayList<TreeNode> getChilden(TreeNode parent) {
ArrayList<TreeNode> child = new ArrayList<TreeNode>();
if(parent.left != null) child.add(parent.left);
if(parent.right != null) child.add(parent.right);
return child;
}
/*Gets all the possible Compinations*/
void getPermutations(ArrayList<TreeNode> permutations, LinkedList<Long> current) {
if(permutations.size() == 0) {
result.add(current);
return;
}
int length = permutations.size();
for(int i = 0; i < length; i++) {
TreeNode node = permutations.get(i);
permutations.remove(i);
ArrayList<TreeNode> newPossibilities = new ArrayList<TreeNode>();
newPossibilities.addAll(permutations);
newPossibilities.addAll(getChilden(node));
LinkedList<Long> newCur = new LinkedList<Long>();
newCur.addAll(current);
newCur.add(node.val);
getPermutations(newPossibilities, newCur);
permutations.add(i,node);
}
}
/*This method returns a array of arrays which will lead to a given BST*/
ArrayList<LinkedList<Long>> inputSequencesForBst(TreeNode node) {
result = new ArrayList<LinkedList<Long>>();
if(node == null)
return result;
ArrayList<TreeNode> permutations = getChilden(node);
LinkedList<Long> current = new LinkedList<Long>();
current.add(node.val);
getPermutations(permutations, current);
return result;
}
}
My solution. Works perfectly.
Here's my Python solution with plenty of explanation.
We build each array from left to right by choosing for every position one node out of a set of possible choices for that position. We add the node value to the path, and the children of the node (if any) to the list of possibilities, then recurse further. When there are no further choices we have one candidate array. To generate the rest of the the arrays, we backtrack until we can make a different choice and recurse again.
The catch is to use a suitable data structure for holding the possibilities. A list works, but the node has to be put back in the previous position while backtracking (order matters, since we have added the children of the node which must be visited AFTER the node). Insertion and deletion from a list takes linear time. A set doesn't work since it doesn't maintain order. A dict works best since Python dictionary remembers the insertion order and all operations run in constant time.
def bst_seq(root: TreeNode) -> list[list[int]]:
def _loop(choices: MutableMapping[TreeNode, bool], path: list[int], result: list[list[int]]) -> None:
if not choices:
result.append([*path])
else:
# Take a snapshot of the keys to avoid concurrent modification exception
for choice in list(choices.keys()):
del choices[choice]
children = list(filter(None, [choice.left, choice.right]))
for child in children:
choices[child] = False
path.append(choice.val)
_loop(choices, path, result)
path.pop()
choices[choice] = False
for child in children:
del choices[child]
result = []
_loop({root: False}, [], result)
return result