I'm using the Deque to implement a monotonic queue. I know that Deque can be created by both ArrayDeque and LinkedList. Here is the Monotonic class I constructed:
public static class MonotonicQueue {
Deque<Integer> monotonicQueue;
public MonotonicQueue() {
monotonicQueue = new ArrayDeque<>();
}
void push(int n) {
while (!monotonicQueue.isEmpty() && monotonicQueue.getLast() < n) {
monotonicQueue.removeLast();
}
monotonicQueue.addLast(n);
}
int max() {
return monotonicQueue.getFirst();
}
void pop(int n) {
if (!monotonicQueue.isEmpty() && n == monotonicQueue.getFirst()) {
monotonicQueue.removeFirst();
}
monotonicQueue.addLast(n);
}
}
However, the issue appears in the void push(int n) method, which means delete all elements which are < n, and then add n into the queue of the tail. I initialized a variable window in a method and then tried to push an element to update this monotonic queue.
MonotonicQueue window = new MonotonicQueue();
window.push(3);
But it even fails to insert the first element. The weird thing is when I use the second way in the constructor, say LinkedList<> instead of ArrayDeque, it works very well, i.e. 3 can be inserted successfully.
public MonotonicQueue() {
monotonicQueue = new LinkedList<>();
}
I am wondering why one way works but the other can't. What happened here? Thank you!
Related
In my case, I want to create a binary tree by taking the depth as the input.
For example, if I do tree.create(3), there will generate a binary tree when the depth of the deepest left is three, which means there will be 2^3 - 1 nodes in the tree and the value of all of them will be 0. The index will be 0 - 6 accorndingly.
class Tree<T> {
int depth;
int index;
T value;
public Tree(int index,T value) {
this.index = index;
this.value = value;
}
public static <K> Tree<K> create(int depth){
if(depth >= 1) {
//return a tree with the inputting depth,
//but I don't know how to do in this step
return new Tree(...?)
}
}
}
Which part of knowledge shall I use to achieve this in Java? Thanks!
Usually when working with a binary tree data structure you need to write recursive methods. When writing a recursive method, you need to write a condition that terminates the recursion. In your case, the recursion will end if we have reached the desired depth. In order to determine if we have reached the desired depth, we need to know what that desired depth is and what the current depth is. I will assume that the depth of the root node in the binary tree is zero. This means that for a maximum depth of 3 (as in the example in your question), the deepest level will be level 2. If we have not reached the desired depth, then I need to add a left and a right child node and then call the same method on each of those children and make sure that the depth of the child nodes is one greater than the depth of the parent. So my recursive method needs three parameters:
a node to (possibly) add child nodes to
the current depth
the maximum depth
Note that I don't need to handle the value (or data) that each node contains because you state, in your question, that each node will have the same value. Hence I can simply copy the value from the parent node to each of its children.
Here is a complete example. Note that when I tested it, a depth greater than 25 causes an OutOfMemoryError because there is a limit on how many recursive method invocations can be done.
import java.util.ArrayList;
import java.util.List;
public class BinTree<T> {
BinTreeNode<T> root;
public static <T> BinTree<T> create(int depth, T val) {
if (depth > 0) {
BinTree<T> theTree = new BinTree<>();
theTree.root = new BinTreeNode<>(val);
theTree.addLevel(theTree.root, 0, depth);
return theTree;
}
else {
throw new IllegalArgumentException("Invalid depth: " + depth);
}
}
public void getAllElements(BinTreeNode<T> aNode, List<T> list) {
if (aNode == null) {
return;
}
else {
getAllElements(aNode.left, list);
list.add(aNode.genericObject);
getAllElements(aNode.right, list);
}
}
private void addLevel(BinTreeNode<T> theNode, int level, int deepest) {
if (level == deepest - 1) {
return;
}
theNode.left = new BinTreeNode<>(theNode.genericObject);
theNode.right = new BinTreeNode<>(theNode.genericObject);
addLevel(theNode.left, level + 1, deepest);
addLevel(theNode.right, level + 1, deepest);
}
public static void main(String[] args) {
BinTree<String> aTree = BinTree.create(3, "George"); // max depth = 25
List<String> list = new ArrayList<>();
aTree.getAllElements(aTree.root, list);
System.out.println(list.size());
}
}
class BinTreeNode<T> {
BinTreeNode<T> left, right;
T genericObject;
public BinTreeNode(T obj) {
genericObject = obj;
}
}
Note that I added method getAllElements as a test to see whether the correct number of nodes were created.
I'm trying to implement Queues in JAVA. I'm a beginner. I dont understand why this isn't working. Push() works fine but pop() isn't working. Can someone please point out where im going wrong?
pop():
public void pop()
{
for(int i=0;i<length;i++)
{
while(i<(length-1))
{
arr[i]=arr[i+1];
}
}
}
push():
public void push(int x)
{
push:for(int i=0;i<length;i++)
{
if(arr[i]==null)
{
arr[i]=x;
break push;
}
}
}
show():
public void show()
{
int c=0;
for(int i=0;i<length;i++)
//if(arr[i]!=null)
{
System.out.println(arr[i]);
c++;
}
System.out.println("Current Capacity "+c+"/"+length);
}
main()
public static void main(String...i)
{
System.out.println("Stack Implementation");
Queue stack = new Queue();
System.out.println("Push");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.show();
System.out.println("Pop");
stack.pop();
stack.show();
}
The output doesn't show any data after pop() is run.
You don't increment i in pop() so the while loop will run endlessly.
In push you are using a for loop which increments i: :for(int i=0;i<length;i++ /*here*/)
You also don't initialize i in pop() so it will probably have the value of the last increment in push(). That value will be the index of the next empty element (if there's one left) and thus that's wrong anyways. However, you want to pop from the front, so you'd need to start at i = 0 - in that case another for loop would work as well, i.e. you just copy the value of element at i+1 to the index i and set the last element to null (for more efficiency you could stop once i+1 has a null element).
Edit: now that you've posted more code for pop() the situation is a little different. You are already using a for loop in pop() but another loop inside that. I assume you want to do if(i<(length-1)) instead of while(i<(length-1)) - but in that case you'd still have to handle the last element, i.e. once the queue was full you'd need to set the last element to null when you pop one and move the rest.
When you pushed the element you need to return from the method:
public void push(int x) {
for (int i = 0; i < length; i++) {
if (arr[i] == null) {
arr[i] = x;
return; // Exit from push when you added the element in the right position
}
}
}
Note that this code is not optimized. Push an element requires O(n), so can waste a lot of time for big queues, but this is the closest solution to your code. Anyway a simple optimization can be done introducing a variable holding the last used index. So you can use that variable to push and pop an element in O(1).
How would I reverse a queue without having a parameter. I'm trying to copy elements from another queue not in the method and reverse the elements. I have the algorithm but I don't know how to access original queue to copy.
public QueueInterface<T> reverseQueue() {
// TODO 8
Queue<T> a = new Queue<T>();
Stack<T> b = new Stack<T>();
while(!a.isEmpty()){
b.push(a.dequeue());
}
while(!b.isEmpty()){
a.enqueue(b.pop());
}
return a;
}
So I added this condition to add elements to a variable temp and run it through a recursive loop but it gives an error message that would be shown if the queue is empty, NoSuchElementException. Would it be easier to create another Queue instead of temp and place elements inside that or some other way.
public QueueInterface<T> reverseQueue() {
T temp = null;
Queue<T> a = new Queue<T>();
if (temp == null) {
temp = dequeue();
a.enqueue(temp);
reversed();
}
I'm trying to used recursive method to complete the addLast method in a singly linked list, however, the code gives me a wrong output of list.size() = 2 and list.getFirst() = 5. The reason should be due to the line
SLList p=this;
It seems changing p reference changes "this" reference as well, which is not so logic to me. Could anyone give some details about this? Thx
public class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
/** Adds an item to the front of the list. */
public void addFirst(int x) {
first = new IntNode(x, first);
}
/** Retrieves the front item from the list. */
public int getFirst() {
return first.item;
}
/** Adds an item to the end of the list. */
public void addLast(int x) {
SLList p = this;
if (p.first. next == null) {
p.first.next = new IntNode (x, null);
}
else {
p.first = p.first.next;
p.addLast(x);
}
}
/** Returns the number of items in the list using recursion. */
public int size() {
/* Your Code Here! */
SLList p = this;
if (p.first == null) {
return 0;
}
else if (p.first.next == null){
return 1;
}
else {
p.first = p.first.next;
return 1 + p.size();
}
}
public static void main (String[] args) {
SLList list=new SLList (5);
list.addFirst(10);
list.addFirst(15);
list.addLast(17);
System.out.println(list.getFirst());
System.out.println(list.size());
}
}
The problem is nothing to do with the assignment of this. Nothing can change this. Period.
(But things can change the state of the object that this refers to.)
The real problem is in your implementation of the size method. Your size method is causing the list to change. It shouldn't. In your case, the change causes:
the size() method to return the wrong value
subsequent getFirst() calls to return the wrong value.
I won't say exactly where the bug, but you should be able to spot it yourself by a process of elimination. (Or if that fails, use a debugger and try to observe where the list is changing.)
There are bigger problems with your algorithms than you think. size() is incorrect. You can fix this if you realize that you need to count the number of IntNode objects in the list. Similarly all other methods need to manipulate IntNode objects.
SLList p = this;
p reference to the same SLList object. if you make any changes to 'p' then it will also happened to 'this', becuase of reference type (not value type).
Here in the statement
p.first = p.first.next;
the reference to the first is changed when you call 'addLast' method. You loss the reference to the first item.
If you remove the line
list.addLast(17);
in main method you will see the correct answer. The problem is with this method.
Change the method as follow and add the new method below.
/** Adds an item to the end of the list. */
public void addLast(int x) {
addLast(x, this.first);
}
private void addLast(int x, IntNode node){
if(node.next == null){
node.next = new IntNode (x, null);
}else {
node = node.next;
addLast(x, node);
}
}
Then you will not lose the reference to first item and now it works fine,
Problem in your implementation is addLast and size method are changing the value of field variable first.
It don't matter whether you assignthis to some variable or use directly.
Because assigning this to some variable does not create new this object but assign's reference to that variable.
So you should first copy value of first field variable to some local variable then iterate on it.In this way your first will not change.
Hint: Don't change the first variable reference.
Your addLast() and size() changes value of first which is wrong.
Problem is in this line.
p.first = p.first.next;
I'm looking for a data structure that is basically a bounded stack.
If I declare that the stack can hold at most 3 items, and I push another item in,
the oldest item is popped.
You'll be able to implement this using a wrapper over a deque (http://en.wikipedia.org/wiki/Deque), or double-ended queue. Just make sure to call the pollLast method inside the offerFirst method if the stack size is reached.
I'd write my own Deque implementation based on a ring buffer.
You need a queue. A singly linked list that records the first and last items.
A doubly linked one if you would like to change from O(n) to O(1) traversal to update the last item.
You push objects at the front of the queue. And if the length is greater than 3, you pop the back.
Well a LIFO (Last In First Out) structure is known as a Stack which is what you need for the main part of your requirement
A FIFO (First In First Out) structure is known as a Queue which is what you need for the ability to pop the oldest Items off the back.
A combination of these is known as a Deque. Where you have to the ability to push or pop from either end.
I'm not sure if Java has a built-in Deque datastructure, but if it does (or you can find an implementation on google), You can just put some wrapping logic around to ensure that if you push to the front, and the deque.Count > 3, then also pop from the back.
This is in C# as I don't know Java I'm afraid but the idea should translate.
public class BoundedStack<T>
{
private readonly int limit;
private LinkedList<T> list;
public BoundedStack(int limit)
{
this.limit = limit;
list = new LinkedList<T>();
}
public void Push(T item)
{
if (list.Count == limit) list.RemoveFirst();
list.AddLast(item);
}
public T Pop()
{
if (list.Count == 0)
throw new IndexOutOfRangeException("No items on the stack");
var item = list.Last.Value;
list.RemoveLast();
return item;
}
public int Count()
{
return list.Count;
}
}
Apache commons has something close to what you need except it is Fifo: CircularFifoBuffer. I think you will be stuck writing a custom wrapper to make a Lifo like implementation.
Here is my LIFO implementation, inspired by Garry Shutler's answer
public class BoundedStack<T> {
private int limit;
private LinkedList<T> list;
public BoundedStack(int limit) {
this.limit = limit;
list = new LinkedList<>();
}
public void push(T item) {
if (list. size() == limit) {
list.removeLast();
}
list.addFirst(item);
}
public int size() {
return list.size();
}
public List<T> getAll() {
return list;
}
public T peek() {
return list.get(0);
}
}