Sort the Values in a Stack - sorting

Hi, this is a simple exercise and here is one of the answer code:
class CheckSort {
public static void sortStack(Stack<Integer> stack) {
//1. Use a second tempStack.
//2. Pop value from mainStack.
//3. If the value is greater or equal to the top of tempStack, then push the value in tempStack
//else pop all values from tempStack and push them in mainStack and in the end push value in tempStack and repeat from step 2.
//till mainStack is not empty.
//4. When mainStack will be empty, tempStack will have sorted values in descending order.
//5. Now transfer values from tempStack to mainStack to make values sorted in ascending order.
Stack<Integer> newStack = new Stack<>(stack.getMaxSize());
while (!stack.isEmpty()) {
Integer value = stack.pop();
if (!newStack.isEmpty() && value >= newStack.top()) {
newStack.push(value);
} else {
while (!newStack.isEmpty() && newStack.top() > value)
stack.push(newStack.pop());
newStack.push(value);
}
}
while (!newStack.isEmpty())
stack.push(newStack.pop());
}
public static void main(String args[]) {
Stack<Integer> stack = new Stack<Integer>(7);
stack.push(2);
stack.push(97);
stack.push(4);
stack.push(42);
stack.push(12);
stack.push(60);
stack.push(23);
sortStack(stack);
while(!stack.isEmpty()){
System.out.println(stack.pop());
}
}
}
I don't understand this part:
} else {
while (!newStack.isEmpty() && newStack.top() > value)
stack.push(newStack.pop());
newStack.push(value);
So when the top element in the new stack is greater than the original stack, we push the value from the new stack to the original stack and then push the value back to the new stack ??
I am totally lost here!! Could someone help me explain this part? Thanks a looooot!!!

The code only needs the else part, and this simpler version is faster if there are a lot of duplicate values. I didn't find any data patterns where this simpler version was slower then the code in the question.
public static void sortStack(Stack<Integer> stack) {
Stack<Integer> newStack = new Stack<>();
Integer value;
while (!stack.isEmpty()) {
value = stack.pop();
while (!newStack.isEmpty() && newStack.peek() > value)
stack.push(newStack.pop());
newStack.push(value);
}
while (!newStack.isEmpty())
stack.push(newStack.pop());
}
Link to a C++ example with an explanation.
https://www.geeksforgeeks.org/sort-stack-using-temporary-stack
If two temporary stacks are used, time complexity can be reduced from O(n^2) to O(n log(n)) using polyphase merge sort, but the code is complicated.

Related

Build a Queue with a limitation of Array of size 5 - but queue can grow

Question: Build a queue class with the enqueue and dequeue methods. However, the language you are using has a bug which does not allow arrays to store more than 5 elements, how would you build that?
I wrote the below code and I was rejected, curious to understand what is the issue and why I was rejected, fyi - this is in technical phone screen.
static LinkedList<Queue<Integer>> list = new LinkedList<Queue<Integer>>();
public static void enQueue(Integer element){
//iterating the linkedlist....
while(true){ //todo
Queue<Integer> curr;
if(list.size() > 0)
curr = list.getLast();
else{
curr = new LinkedList<Integer>();
list.add(curr);
}
if(curr.size() < 5){
curr.add(element);
System.out.println("enqueued:" + element);
break;
} else{
Queue<Integer> newQueue = new LinkedList<Integer>();
newQueue.add(element);
list.add(newQueue); //adding the new Queue of size(5) to the list
break;
}
}
}
public static Integer deQueue(){
LinkedList<Queue<Integer>> node = list;
if(!isEmpty()){
Integer retValue = 0;
while(list.size() > 0){
Queue<Integer> q = node.getFirst();
if(!q.isEmpty()){
retValue = q.poll();
break;
}else{
node.removeFirst();
}
}
return retValue;
}else{
System.out.println("No such element found");
return -1; //throw new NoSuchElementException("no element found");
}
}
public static boolean isEmpty(){
return list.size() == 0;
}
You were rejected, because:
you assumed a pre-existing Queue class, which is what you were supposed to implement.
you used a LinkedList, which already implements a queue-like interface, instead of actually implementing a queue.
You used the LinkedList badly -- there is no reason for any kind of loop at all. You could have just had your enQueue and deQueue call LinkedList.add() LinkedList.pollFirst()
The interviewer really wanted you to actually implement a queue. The array limitation is to force you to use a linked implementation, and the interviewer wanted to see you maintain the links properly.
I guess the question is to check on your implementation of queue data structure with arrays, which cannot be more than size of 5.
I would have something like
Class Queue {
int[][] data;
int maxSize = 25; //5 * 5
int[] front;
int[] rear;
Enqeue(int element) {
//Check for queue full
//Increment front last index, if it crosses 5. Increment previous index
//Use the front index identify data element
//Put the data
}
Dequeue() {
//Check for queue empty
//Use the rear index identify data element
//get the data
//Increment rear last index, if it crosses 5. Increment previous index
//Return the data
}
}
The queue size can be easily scaled to big numbers.
Hope it helps!

Two sum data structure problems

I built a data structure for two sum question. In this data structure I built add and find method.
add - Add the number to an internal data structure.
find - Find if there exists any pair of numbers which sum is equal to the value.
For example:
add(1); add(3); add(5);
find(4) // return true
find(7) // return false
the following is my code, so what is wrong with this code?
http://www.lintcode.com/en/problem/two-sum-data-structure-design/
this is the test website, some cases could not be passed
public class TwoSum {
private List<Integer> sets;
TwoSum() {
this.sets = new ArrayList<Integer>();
}
// Add the number to an internal data structure.
public void add(int number) {
// Write your code here
this.sets.add(number);
}
// Find if there exists any pair of numbers which sum is equal to the value.
public boolean find(int value) {
// Write your code here
Collections.sort(sets);
for (int i = 0; i < sets.size(); i++) {
if (sets.get(i) > value) break;
for (int j = i + 1; j < sets.size(); j++) {
if (sets.get(i) + sets.get(j) == value) {
return true;
}
}
}
return false;
}
}
There does not seem to be anything wrong with your code.
However a coding challenge could possibly require a more performant solution. (You check every item against every item, which would take O(N^2)).
The best solution to implement find, is using a HashMap, which would take O(N). It's explained more in detail here.

How to efficiently add the entire English dictionary to a trie data structure

Simply put I want to check if a specified word exists or not.
The lookup needs to be very fast which is why I decided to store the dictionary in a trie. So far so good! My trie works without issues. The problem is filling the trie with a dictionary. What I'm currently doing is looping through every line of a plain text file that is the dictionary and adding each word to my trie.
This is understandably so an extremely slow process. The file contains just about 120 000 lines. If anyone could point me in the right direction for what I could do it would be much appreciated!
This is how I add words to the trie (in Boo):
trie = Trie()
saol = Resources.Load("saol") as TextAsset
text = saol.text.Split(char('\n'))
for new_word in text:
trie.Add(new_word)
And this is my trie (in C#):
using System.Collections.Generic;
public class TrieNode {
public char letter;
public bool word;
public Dictionary<char, TrieNode> child;
public TrieNode(char letter) {
this.letter = letter;
this.word = false;
this.child = new Dictionary<char, TrieNode>();
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode(' ');
}
public void Add(string word) {
TrieNode node = root;
bool found_letter;
int c = 1;
foreach (char letter in word) {
found_letter = false;
// if current letter is in child list, set current node and break loop
foreach (var child in node.child) {
if (letter == child.Key) {
node = child.Value;
found_letter = true;
break;
}
}
// if current letter is not in child list, add child node and set it as current node
if (!found_letter) {
TrieNode new_node = new TrieNode(letter);
if (c == word.Length) new_node.word = true;
node.child.Add(letter, new_node);
node = node.child[letter];
}
c ++;
}
}
public bool Find(string word) {
TrieNode node = root;
bool found_letter;
int c = 1;
foreach (char letter in word) {
found_letter = false;
// check if current letter is in child list
foreach (var child in node.child) {
if (letter == child.Key) {
node = child.Value;
found_letter = true;
break;
}
}
if (found_letter && node.word && c == word.Length) return true;
else if (!found_letter) return false;
c ++;
}
return false;
}
}
Assuming that you don't have any serious implementation problems, pay the price for populating the trie. After you've populated the trie serialize it to a file. For future needs, just load the serialized version. That should be faster that reconstructing the trie.
-- ADDED --
Looking closely at your TrieNode class, you may want to replacing the Dictionary you used for child with an array. You may consume more space, but have a faster lookup time.
Anything you do with CLI yourself will be slower then using the built-in functions.
120k is not that much for a dictionary.
First thing I would do is fire up the code performance tool.
But just some wild guesses: You have a lot of function calls. Just starting with the Boo C# binding in a for loop. Try to pass the whole text block and tare it apart with C#.
Second, do not use a Dictionary. You waste just about as much resources with your code now as you would just using a Dictionary.
Third, sort the text before you go inserting - you can probably make some optimizations that way. Maybe just construct a suffix table.

How can I find a middle element in a linked list?

How can I find a middle element in a linked list by traversing the entire list only once?
The length of the list is not given, and I am allowed to only use two pointers. How can this be done?
I don't see how you could do it without traversing the entire list unless you know the length.
I'm guessing the answer wants one pointer to be traversing one element at a time, while the second pointer moves 2 elements at a time.
This way when the second pointer reaches the end, the first pointer will be at the middle.
The below code will help you get the middle element.
You need to use two pointers "fast" and "slow". At every step the fast pointer will increment by two and slower will increment by one. When the list will end the slow pointer will be at the middle.
Let us consider the Node looks like this
class Node
{
int data;
Node next;
}
And LinkedList has a getter method to provide the head of the linked list
public Node getHead()
{
return this.head;
}
The below method will get the middle element of the list (Without knowing the size of the list)
public int getMiddleElement(LinkedList l)
{
return getMiddleElement(l.getHead());
}
private int getMiddleElement(Node n)
{
Node slow = n;
Node fast = n;
while(fast!=null && fast.next!=null)
{
fast = fast.next.next;
slow = slow.next;
}
return slow.data;
}
Example:
If the list is 1-2-3-4-5 the middle element is 3
If the list is 1-2-3-4 the middle element is 3
In C, using pointers, for completeness. Note that this is based on the "Tortoise and Hare" algorithm used for checking if a linked list contains a cycle.
Our node is defined as the following:
typedef struct node {
int val;
struct node *next;
} node_t;
Then our algorithm is thus:
node_t *
list_middle (node_t *root)
{
node_t *tort = root;
node_t *hare = root;
while (hare != NULL && hare->next != NULL) {
tort = tort->next;
hare = hare->next->next;
}
return (tort);
}
For a list with an even number of nodes this returns the node proceding the actual centre (e.g. in a list of 10 nodes, this will return node 6).
There are two possible answers one for odd and one for even, both having the same algorithm
For odd: One pointer moves one step and second pointer moves two element as a time and when the second elements reach the last element, the element at which the first pointer is, the mid element. Very easy for odd.
Try: 1 2 3 4 5
For even: Same, One pointer moves one step and second pointer moves two element as a time and when the second elements cannot jump to next element, the element at which the first pointer is, the mid element.
Try: 1 2 3 4
LinkedList.Node current = head;
int length = 0;
LinkedList.Node middle = head;
while(current.next() != null){
length++;
if(length%2 ==0){
middle = middle.next();
}
current = current.next();
}
if(length%2 == 1){
middle = middle.next();
}
System.out.println("length of LinkedList: " + length);
System.out.println("middle element of LinkedList : " + middle);
Using a size variable you can maintain the size of the Linked list.
public class LinkedList {
private Node headnode;
private int size;
public void add(int i) {
Node node = new Node(i);
node.nextNode = headnode;
headnode = node;
size++;
}
public void findMiddleNode(LinkedList linkedList, int middle) {
Node headnode = linkedList.getHeadnode();
int count = -1;
while (headnode != null) {
count++;
if(count == middle) {
System.out.println(headnode.data);
}else {
headnode = headnode.nextNode;
}
}
}
private class Node {
private Node nextNode;
private int data;
public Node(int data) {
this.data = data;
this.nextNode = null;
}
}
public Node getHeadnode() {
return headnode;
}
public int getSize() {
return size;
}
}
Then from a client method find the middle of the size of the list:
public class MainLinkedList {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add(5);
linkedList.add(3);
linkedList.add(9);
linkedList.add(4);
linkedList.add(7);
linkedList.add(99);
linkedList.add(34);
linkedList.add(798);
linkedList.add(45);
linkedList.add(99);
linkedList.add(46);
linkedList.add(22);
linkedList.add(22);
System.out.println(linkedList.getSize());
int middle = linkedList.getSize()/2;
linkedList.findMiddleNode(linkedList, middle);
}
}
I don’t know if this is better than the two node way, but here also you don’t have to traverse through the entire loop.
Using C# to find a middle element of the linked list:
static void Main(string[] args)
{
LinkedList<int> linked = new LinkedList<int>();
linked.AddLast(1);
linked.AddLast(3);
linked.AddLast(5);
linked.AddLast(6);
linked.AddFirst(12);
Console.WriteLine("Middle Element - " + ListMiddle<int>(linked));
Console.ReadLine();
}
public static T ListMiddle<T>(IEnumerable<T> input)
{
if (input == null)
return default(T);
var slow = input.GetEnumerator();
var fast = input.GetEnumerator();
while (slow.MoveNext())
{
if (fast.MoveNext())
{
if (!fast.MoveNext())
return slow.Current;
}
else
{
return slow.Current;
}
}
return slow.Current;
}
The below Java methods finds the middle of a linked list. It uses two pointers:
Slow pointers which moves by one in each iteration.
A fast pointer which moves twice in each iteration.
The slow pointer will point to the middle when fast reaches the end of the list
public SinglyLinkedListNode getMiddle(SinglyLinkedListNode list) {
if (list == null)
return null;
SinglyLinkedListNode fastPtr = list.next;
SinglyLinkedListNode slowPtr = list;
while (fastPtr != null) {
fastPtr = fastPtr.next;
if (fastPtr != null) {
slowPtr = slowPtr.next;
fastPtr = fastPtr.next;
}
}
return slowPtr;
}
For a doubly-linked list with given pointers to the head and tail node:
We can use both head and tail traversal:
p = head;
q = tail;
while(p != q && p->next != q)
{
p = p->next;
q = q->prev;
}
return p;
Introducing a pointer to the middle node may be an option, but functions like insertNode and deleteNode have to modify this pointer.
Python code for a middle element using the two-pointer method:
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def printList(self):
temp = self.head
while(temp):
print(temp.data, end=" ")
temp = temp.next
def insertAtBeg(self, new_data):
new_node = Node(new_data)
if self.head is None:
self.head = new_node
return
new_node.next = self.head
self.head = new_node
def findMiddle(self):
fast_ptr = self.head
slow_ptr = self.head
if(self.head is not None):
while(fast_ptr is not None and fast_ptr.next is not None):
fast_ptr = fast_ptr.next.next
slow_ptr = slow_ptr.next
print('The middle element is ' + str (slow_ptr.data))
if __name__ == '__main__':
mylist = LinkedList()
mylist.insertAtBeg(10)
mylist.insertAtBeg(20)
mylist.insertAtBeg(30)
mylist.findMiddle()
Output:
The middle element is
import java.util.*;
public class MainLinkedList {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add(10);
linkedList.add(32);
linkedList.add(90);
linkedList.add(43);
linkedList.add(70);
linkedList.add(20);
linkedList.add(45);
int middle = linkedList.size()/2;
System.out.println(linkedList.get(middle));
}
}
I am adding my solution which will work for both odd and even number of elements scenarios like:
1-2-3-4-5 middle element 3
1-2-3-4 middle element 2,3
It is inspired by the same fast pointer and slow pointer principle as mentioned in some of the other answers in the post.
public class linkedlist {
Node head;
static class Node {
int data;
Node next;
Node(int d) { data = d; next=null; }
}
public static void main(String args[]) {
linkedlist ll = new linkedlist();
Node one = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
Node fourth = new Node(4);
Node five = new Node(5);
Node sixth = new Node(6);
Node seventh = new Node(7);
Node eight = new Node(8);
ll.head = one;
one.next = second;
second.next = third;
third.next = fourth;
fourth.next = five;
five.next = sixth;
sixth.next = seventh;
seventh.next = eight;
ll.printList();
ll.middleElement();
}
public void printList() {
Node n = head;
while(n != null) {
System.out.print(n.data + " ---> ");
n = n.next;
}
}
public void middleElement() {
Node headPointer = head;
Node headFasterPointer = head;
int counter = 0;
if(head != null) {
while(headFasterPointer.next != null) {
if(headFasterPointer.next.next != null) {
headFasterPointer = headFasterPointer.next.next;
headPointer = headPointer.next;
}
else
{
headFasterPointer = headFasterPointer.next;
}
counter++;
}
System.out.println();
System.out.println("The value of counter is " + counter);
if(counter %2 == 0) {
System.out.println("The middle element is " + headPointer.data + "," + headPointer.next.data);
}
else
{
System.out.println("The middle element is " + headPointer.data);
}
}
}
}
Class Node:
# Function to initialise the node object
def __init__(self, data):
self.data = data
self.next = None
Class LinkedList:
def __init__(self):
self.head = None
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# Function to get the middle of
# the linked list
def printMiddle(self):
slow_ptr = self.head
fast_ptr = self.head
if self.head is not None:
while (fast_ptr is not None and fast_ptr.next is not None):
fast_ptr = fast_ptr.next.next
slow_ptr = slow_ptr.next
print("The middle element is: ", slow_ptr.data)
Driver code
list1 = LinkedList()
list1.push(5)
list1.push(4)
list1.push(2)
list1.push(3)
list1.push(1)
list1.printMiddle()
It's stupid to use two pointers, "fast" and "slow", because the operator next is used 1.5n times. There is no optimization.
Using a pointer to save the middle element can help you:
list* find_mid_1(list* ptr)
{
list *p_s1 = ptr, *p_s2 = ptr;
while (p_s2=p_s2->get_next())
{
p_s2 = p_s2->get_next();
if (!p_s2)
break;
p_s1 = p_s1->get_next();
}
return p_s1;
}

What does ExpressionVisitor.Visit<T> Do?

Before someone shouts out the answer, please read the question through.
What is the purpose of the method in .NET 4.0's ExpressionVisitor:
public static ReadOnlyCollection<T> Visit<T>(ReadOnlyCollection<T> nodes, Func<T, T> elementVisitor)
My first guess as to the purpose of this method was that it would visit each node in each tree specified by the nodes parameter and rewrite the tree using the result of the elementVisitor function.
This does not appear to be the case. Actually this method appears to do a little more than nothing, unless I'm missing something here, which I strongly suspect I am...
I tried to use this method in my code and when things didn't work out as expected, I reflectored the method and found:
public static ReadOnlyCollection<T> Visit<T>(ReadOnlyCollection<T> nodes, Func<T, T> elementVisitor)
{
T[] list = null;
int index = 0;
int count = nodes.Count;
while (index < count)
{
T objA = elementVisitor(nodes[index]);
if (list != null)
{
list[index] = objA;
}
else if (!object.ReferenceEquals(objA, nodes[index]))
{
list = new T[count];
for (int i = 0; i < index; i++)
{
list[i] = nodes[i];
}
list[index] = objA;
}
index++;
}
if (list == null)
{
return nodes;
}
return new TrueReadOnlyCollection<T>(list);
}
So where would someone actually go about using this method? What am I missing here?
Thanks.
It looks to me like a convenience method to apply an aribitrary transform function to an expression tree, and return the resulting transformed tree, or the original tree if there is no change.
I can't see how this is any different of a pattern that a standard expression visitor, other than except for using a visitor type, it uses a function.
As for usage:
Expression<Func<int, int, int>> addLambdaExpression= (a, b) => a + b;
// Change add to subtract
Func<Expression, Expression> changeToSubtract = e =>
{
if (e is BinaryExpression)
{
return Expression.Subtract((e as BinaryExpression).Left,
(e as BinaryExpression).Right);
}
else
{
return e;
}
};
var nodes = new Expression[] { addLambdaExpression.Body }.ToList().AsReadOnly();
var subtractExpression = ExpressionVisitor.Visit(nodes, changeToSubtract);
You don't explain how you expected it to behave and why therefore you think it does little more than nothing.

Resources