I have written a function for reverse a stack inline. these two are member function of stack class .
void reverse()
{
int first=pop();
if(first!=-1)
{
reverse();
insert(first);
}
}
private:
void insert(int i)
{
int temp=pop();
if(temp==-1)
{
push(i);
}
else
{
/* there is already a element in the stack*/
insert(i);
push(temp);
}
}
Now how can i analyze my function in form of big O to calculate complexity.
Your insert() takes O(length of the stack) time because:
T(n) = T(n-1) + O(1)[to push] = O(n)
and your reverse() takes O(square of the length of the stack) time because:
T(n) = T(n-1) + O(n)[for insert] = O(n^2)
Related
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.
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.
I have a basic algorithm of a double-auction mechanism which I am having difficulty finding the Big-O time complexity for. What steps should I take to to rigorously analyse this algorithm?
I know the Big-O notation is a notation for the time complexity of an algorithm, and that it represents the upper bound of the limit of the scaling factor of the algorithm.
However, I am not sure how you would get the second function to define an upper bound to my algorithm.
While (r = min(supply, demand)) {
oa = Pul;
ob = Pll;
While {true} {
nondetermistic choice;
If (a buyer submits a bid:) {
If (bid = ob or out of [Pll, Pul]) {
bid is an invalid bid;
} else {
bid updates ob and becomes a new ob;
}
If (ob = oa) {
Pt = oa;
The round is ended;
}
} ElseIf (a seller submits an ask:) {
If (ask = oa or out of [Pll, Pul]) {
ask is an invalid ask;
} else {
ask updates oa and becomes a new oa;
}
If (ob = oa) {
Pt = ob;
The round is ended;
}
} Else (time out:) {
If (no new oa or ob in a pre-specified time period) {
The round is ended with no transaction;
}
}
end nondetermistic choice ;
}
r = r + 1;
}
I would like to generate and print the first 10 Fibonacci numbers. I don't want to be efficient, but I want to see some (working) X10 code that is easy to understand.
My try
// file Fibonacci.x10
public class Fibonacci {
public static def fib(n:Int): Int {
if (n < 2) {
return n;
}
val f1:Int;
val f2:Int;
finish {
async f1 = fib(n-1);
async f2 = fib(n-2);
}
return f1 + f2;
}
public static def main(args:Rail[String]) {
x10.io.Console.OUT.println("This is fibonacci in X10.");
for (var i:Int=0; i < 10; ++i) {
x10.io.Console.OUT.println(i + ": " + fib(i));
fib(i);
}
}
}
When I compile this, I get:
/home/moose/Fibonacci.x10:11: No valid method call found for call in given type.
Call: fib(x10.lang.Long)
Type: Fibonacci
/home/moose/Fibonacci.x10:12: No valid method call found for call in given type.
Call: fib(x10.lang.Long)
Type: Fibonacci
/home/moose/Fibonacci.x10:19: Cannot assign expression to target; base types are incompatible.
Expression: 0L
Expected base type: x10.lang.Int
Found base type: x10.lang.Long
3 errors.
I use X10 release 2.4.2.
The following version works as expected:
// file Fibonacci.x10
public class Fibonacci {
public static def fib(n:Long): Long {
if (n < 2) {
return n;
}
val f1:Long;
val f2:Long;
finish {
async f1 = fib(n-1);
async f2 = fib(n-2);
}
return f1 + f2;
}
public static def main(args:Rail[String]) {
x10.io.Console.OUT.println("This is fibonacci in X10.");
for (var i:Long=0; i < 10; ++i) {
x10.io.Console.OUT.println(i + ": " + fib(i));
}
}
}
It seems as if number are Long per standard.
I had a quesiton here, but it didn't save. I'm having trouble balancing a fully unbalanced tree (nodes 1-15 along the right side).
I'm having trouble because I get stack overflow.
> // balancing
public void balance(node n) {
if(n != null) {
System.out.println(height(n)-levels);
if (height(n.RCN) != height(n.LCN)) {
if (height(n.RCN) > height(n.LCN)) {
if(height(n.RCN) > height(n.LCN)) {
n = rotateL(n);
n = rotateR(n);
} else {
n = rotateL(n);
}
} else {
if(height(n.LCN) > height(n.RCN)) {
n = rotateR(n);
n = rotateL(n);
} else {
n = rotateR(n);
}
}
balance(n.LCN);
balance(n.RCN);
}
}
}
// depth from node to left
public int heightL(node n) {
if (n == null)
return 0;
return height(n.LCN) + 1;
}
// depth from node from the right
public int heightR(node n) {
if (n == null)
return 0;
return height(n.RCN) + 1;
}
// left rotation around node
public node rotateL(node n) {
if (n == null)
return null;
else {
node newRoot = n.RCN;
n.RCN = newRoot.LCN;
newRoot.LCN = n;
return newRoot;
}
}
// right rotation around node
public node rotateR(node n) {
if (n == null)
return null;
else {
node newRoot = n.LCN;
n.LCN = newRoot.RCN;
newRoot.RCN = n;
return newRoot;
}
}
Doing a rotateL followed by a rotateR ends up doing nothing since you are modifying the same node. n is not the original n. It is the newNode from the function. So basically, n is something like this:
newNode = rotateL(n);
n = rotateR(newNode);
So you are basically leaving the tree unchanged.
I am also unsure as to why you repeat the if (height(n.RCN) > height(n.LCN)) check. I think you meant your first check to be more like abs(height(n.RCN) - height(n.LCN)) > 1 and then use the comparison to determine which way to rotate.
Also, could you add the implementation for height(...)?