Insert Unique element into trie - trie

void insert(struct node *root, string s)
{
struct node *temp = root;
for(int i=0;i<s.length();i++)
{
if(temp->idx[s[i]-'a']==NULL)
temp->idx[s[i]-'a']=create();
temp = temp->idx[s[i]-'a'];
(temp->cnt)++;
}
temp->end=1;
}
So I am going to insert string to create a unique trie data structure, but this insert algortihm is not able to detect any duplicate string, can someone help me how this insert algorithm works only for inserting unique elements?

You can check for string duplicates using end property of struct node. Let's call find to this boolean method and add it as first line of insert method.
bool find(struct node *root, string s)
{
struct node *temp = root;
for(int i=0;i<s.length();i++)
{
if(temp->idx[s[i]-'a']==NULL)
return false;
temp = temp->idx[s[i]-'a'];
}
return temp->end;
}
void insert(struct node *root, string s)
{
if(!find(root, s)) return;
struct node *temp = root;
for(int i=0;i<s.length();i++)
{
if(temp->idx[s[i]-'a']==NULL)
temp->idx[s[i]-'a']=create();
temp = temp->idx[s[i]-'a'];
(temp->cnt)++;
}
temp->end=1;
}
Runtime: The same as before O(m) where m is length of s.
Note: I made find method since anyway you need to traverse at most twice that path of the trie. One way is the mentioned at the beginning, a second one is to check duplicates (end property) when you have the node that represent s and if it is indeed a duplicated string then you traverse again s path fixing the extra +1 in cnt property.

Related

Binary Search Tree Iterator java

I did the LeetCode question Binary Search Tree Iterator. the following code is what I learned from others. One part I didn't understand which is cur = cur.right. Since I got the smallest value of cur.val. Why do I need to assign cur.right to cur? When I remove cur = cur.right, it said time limit exceeded. Could someone can help me to explain it?
public class BSTIterator {
Stack<TreeNode> stack;
TreeNode cur;
public BSTIterator(TreeNode root) {
stack = new Stack<>();
cur = root;
}
/** #return the next smallest number */
public int next() {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
int val = cur.val;
cur = cur.right; //why needed to assign cur.right to cur?
return val;
}
}
By thinking on the structure of a binary search tree we know that the left node is less than the parent (or middle) node, and that the right node is more than the parent (or middle) node. By setting the current node to be equal to the right node you are iterating through the tree in order from least to largest value. Note that if cur.right() doesn't exist then cur will be set to null and therefore not execute the while loop.
I submitted my code, it was successful.
https://leetcode.com/problems/binary-search-tree-iterator/
You can find it here.
https://github.com/yan-khonski-it/bst/blob/master/bst-core/src/main/java/com/yk/training/bst/iterators/BSTIterator.java
Explanation.
You have to use inorder which first visits the left sub-tree, then visit the current node, and then the right sub-tree, so you will iterate through all the elements in the ascending order.
Now, you have stack, which holds all the node that you should return in next call in the correct order.
next will remove the last element from the stack. Now you check the current node, if it has right subtree. If so, you need to iterate though left elements of the right subtree.
/**
* Find next node to be returned in {#link #next()}.
* Push it to stack.
*/
public void navigateLeftSubtree() {
stack.push(currentNode);
while (currentNode.left != null) {
currentNode = currentNode.left;
stack.push(currentNode);
}
}
In this case, (right sub tree is present for current node), you should put the right child of the current node into the stack. You don't want to put the current into the stack, if you have already visited it.
public int next() {
currentNode = stack.pop();
final int currentValue = currentNode.value;
if (currentNode.right != null) {
// Push root of the right subtree into stack.
currentNode = currentNode.right;
navigateLeftSubtree();
}
return currentValue;
}

Sage: Iterate over increasing sequences

I have a problem that I am unwilling to believe hasn't been solved before in Sage.
Given a pair of integers (d,n) as input, I'd like to receive a list (or set, or whatever) of all nondecreasing sequences of length d all of whose entries are no greater than n.
Similarly, I'd like another function which returns all strictly increasing sequences of length d whose entries are no greater than n.
For example, for d = 2 n=3, I'd receive the output:
[[1,2], [1,3], [2,3]]
or
[[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
depending on whether I'm using increasing or nondecreasing.
Does anyone know of such a function?
Edit Of course, if there is such a method for nonincreasing or decreasing sequences, I can modify that to fit my purposes. Just something to iterate over sequences
I needed this algorithm too and I finally managed to write one today. I will share the code here, but I only started to learn coding last week, so it is not pretty.
Idea Input=(r,d). Step 1) Create a class "ListAndPosition" that has a list L of arrays Integer[r+1]'s, and an integer q between 0 and r. Step 2) Create a method that receives a ListAndPosition (L,q) and screens sequentially the arrays in L checking if the integer at position q is less than the one at position q+1, if so, it adds a new array at the bottom of the list with that entry ++. When done, the Method calls itself again with the new list and q-1 as input.
The code for Step 1)
import java.util.ArrayList;
public class ListAndPosition {
public static Integer r=5;
public final ArrayList<Integer[]> L;
public int q;
public ListAndPosition(ArrayList<Integer[]> L, int q) {
this.L = L;
this.q = q;
}
public ArrayList<Integer[]> getList(){
return L;
}
public int getPosition() {
return q;
}
public void decreasePosition() {
q--;
}
public void showList() {
for(int i=0;i<L.size();i++){
for(int j=0; j<r+1 ; j++){
System.out.print(""+L.get(i)[j]);
}
System.out.println("");
}
}
}
The code for Step 2)
import java.util.ArrayList;
public class NonDecreasingSeqs {
public static Integer r=5;
public static Integer d=3;
public static void main(String[] args) {
//Creating the first array
Integer[] firstArray;
firstArray = new Integer[r+1];
for(int i=0;i<r;i++){
firstArray[i] = 0;
}
firstArray[r] = d;
//Creating the starting listAndDim
ArrayList<Integer[]> L = new ArrayList<Integer[]>();
L.add(firstArray);
ListAndPosition Lq = new ListAndPosition(L,r-1);
System.out.println(""+nonDecSeqs(Lq).size());
}
public static ArrayList<Integer[]> nonDecSeqs(ListAndPosition Lq){
int iterations = r-1-Lq.getPosition();
System.out.println("How many arrays in the list after "+iterations+" iterations? "+Lq.getList().size());
System.out.print("Should we stop the iteration?");
if(0<Lq.getPosition()){
System.out.println(" No, position = "+Lq.getPosition());
for(int i=0;i<Lq.getList().size();i++){
//Showing particular array
System.out.println("Array of L #"+i+":");
for(int j=0;j<r+1;j++){
System.out.print(""+Lq.getList().get(i)[j]);
}
System.out.print("\nCan it be modified at position "+Lq.getPosition()+"?");
if(Lq.getList().get(i)[Lq.getPosition()]<Lq.getList().get(i)[Lq.getPosition()+1]){
System.out.println(" Yes, "+Lq.getList().get(i)[Lq.getPosition()]+"<"+Lq.getList().get(i)[Lq.getPosition()+1]);
{
Integer[] tempArray = new Integer[r+1];
for(int j=0;j<r+1;j++){
if(j==Lq.getPosition()){
tempArray[j] = new Integer(Lq.getList().get(i)[j])+1;
}
else{
tempArray[j] = new Integer(Lq.getList().get(i)[j]);
}
}
Lq.getList().add(tempArray);
}
System.out.println("New list");Lq.showList();
}
else{
System.out.println(" No, "+Lq.getList().get(i)[Lq.getPosition()]+"="+Lq.getList().get(i)[Lq.getPosition()+1]);
}
}
System.out.print("Old position = "+Lq.getPosition());
Lq.decreasePosition();
System.out.println(", new position = "+Lq.getPosition());
nonDecSeqs(Lq);
}
else{
System.out.println(" Yes, position = "+Lq.getPosition());
}
return Lq.getList();
}
}
Remark: I needed my sequences to start at 0 and end at d.
This is probably not a very good answer to your question. But you could, in principle, use Partitions and the max_slope=-1 argument. Messing around with filtering lists of IntegerVectors sounds equally inefficient and depressing for other reasons.
If this has a canonical name, it might be in the list of sage-combinat functionality, and there is even a base class you could perhaps use for integer lists, which is basically what you are asking about. Maybe you could actually get what you want using IntegerListsLex? Hope this proves helpful.
This question can be solved by using the class "UnorderedTuples" described here:
http://doc.sagemath.org/html/en/reference/combinat/sage/combinat/tuple.html
To return all all nondecreasing sequences with entries between 0 and n-1 of length d, you may type:
UnorderedTuples(range(n),d)
This returns the nondecreasing sequence as a list. I needed an immutable object (because the sequences would become keys of a dictionary). So I used the "tuple" method to turn the lists into tuples:
immutables = []
for s in UnorderedTuples(range(n),d):
immutables.append(tuple(s))
return immutables
And I also wrote a method which picks out only the increasing sequences:
def isIncreasing(list):
for i in range(len(list) - 1):
if list[i] >= list[i+1]:
return false
return true
The method that returns only strictly increasing sequences would look like
immutables = []
for s in UnorderedTuples(range(n),d):
if isIncreasing(s):
immutables.append(tuple(s))
return immutables

Building a linked list in yacc with left recursive Grammar

I want to build a linked list of data in yacc.
My Grammar reads like this:
list: item
| list ',' item
;
I have put the appropriate structures in place in the declarations section. But I am not able to figure out a way to get a linked list out of this data. I have to store the recursively obtained data and then redirect it for other purposes.
Basically I am looking for a solution like this one:
https://stackoverflow.com/a/1429820/5134525
But this solution is for right recursion and doesn't work with left.
It depends heavily on how you implement your linked list, but once you have that, it is straight-forward. Something like:
struct list_node {
struct list_node *next;
value_t value;
};
struct list {
struct list_node *head, **tail;
};
struct list *new_list() {
struct list *rv = malloc(sizeof(struct list));
rv->head = 0;
rv->tail = &rv->head;
return rv; }
void push_back(struct list *list, value_t value) {
struct list_node *node = malloc(sizeof(struct list_node));
node->next = 0;
node->value = value;
*list->tail = node;
list->tail = &node->next; }
allows you to write your yacc code as:
list: item { push_back($$ = new_list(), $1); }
| list ',' item { push_back($$ = $1, $3); }
;
of course, you should probably add checks for running out of memory, and exit gracefully in that case.
If you use a left recursive rule, then you need to push the new item at the end of the list rather than the beginning.
If your linked list implementation doesn't support push_back, then push the successive items at the front and reverse the list when its finished.
Very simple.
list
: item
{
$$ = new MyList<SomeType>();
$$.add($1);
}
| list ',' item
{
$1.add($3);
$$ = $1;
}
;
assuming you are using C++, which you didn't state, and assuming you have some MyList<T> class with an add(T) method.

binary search tree - insert right node gives null pointer exxception

I am trying to insert node into a binary search tree
inserting a node in the left subtree is giving no issues
but inserting a node at right subtree is giving issue of null pointer exception.
inserting a node first time work properly but when I try to insert a new node in the right part of the root, I found the root has already been given some garbage value while traversing n it prints null pointer exception.
typedef struct tree
{
int elt;
struct tree *left,*right;
}T;
T *RT=null;
void insert()
{
int n;
T *move,*temp,*back;
printf("\nEnter an element: ");
scanf("%d",&n);
temp=(T *)malloc(sizeof(T *));
temp->left=NULL;
temp->right=NULL;
temp->elt=n;
if(RT==NULL)
RT=temp;
else
{
move=RT;
while(move!=NULL)
{
back=move;
if(move->elt>=n)
move=move->left;
else if(move->elt<n)
move=move->right;
}
if(back->elt>=n)
back->left=temp;
else
back->right=temp;
}
printf("%d %d %d",RT->elt,RT->left->elt,RT->right->elt);
}

Merge two Binary trees

public int merge(BNode node, int array[], int i) {
if (node == null)
return i;
//Flatten left subtree
i = merge(node.left, array, i);
//Get data from the current node
array[i] = node.value;
//Flatten right subtree
i = merge(node.right, array, i + 1);
return i;
}
I'm trying to merge two binary trees and retain the BST property.
The approach im using is to flatten the trees and store them in arrays.
The function above flattens my first tree and stores it in the array[] .
I want a function which would take the rootnode and blank array[] as input and RETURNS me a flattened tree with all the nodes into an array.
As you are doing, if you want to merge 2 binary search tree, the best way is:
1)Flatten trees into sorted lists.
2)Merge lists.
3)Transform the merged list to a BST.
You can implement the function you are looking for easily this way:
BinarySearchTree* arrayToTree(int arr[], int start, int end) {
if (start > end) return NULL;
int mid = start + (end - start) / 2;
BinarySearchTree *node = new BinarySearchTree(arr[mid]);
node->left = arrayToTree(arr, start, mid-1);
node->right = arrayToTree(arr, mid+1, end);
return node;
}
BinarySearchTree* arrayToTree(int arr[], int n) {
return arrayToTree(arr, 0, n-1);
}