pop() function for stack referred by min not working properly? - java

I was attempting a question on leetcode and not sure about this anomalous behaviour. I am providing the logic part of the question. Please let me know if any discrepancy is found.
Question: Design a stack that supports push, pop, top, and retrieving
the minimum element in constant time.
push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
getMin() -- Retrieve the minimum element in the stack.
Link to leetcode question
Approach: Using 2 stacks, values (with original values in their order) and min (with values sorted in ascending order)
class MinStack {
Stack<Integer> min;
Stack<Integer> values;
/** initialize your data structure here. */
public MinStack() {
min = new Stack<>();
values = new Stack<>();
}
public void push(int x) {
if(values.isEmpty()){
values.push(x);
min.push(x);
}
else{
values.push(x);
if(min.peek()<x){
List<Integer> list = new ArrayList<>();
while(!min.isEmpty() && min.peek()<x)
list.add(min.pop());
min.push(x);
for(int i=list.size()-1;i>=0;i--)
min.push(list.get(i));
}
else
min.push(x);
}
System.out.println("min after push-->"+min);
System.out.println("values after push -->"+values);
}
public void pop() {
if(values.peek()==min.peek()){
min.pop();
}
else{
List<Integer> list = new ArrayList<>();
while(!min.isEmpty() && min.peek()!=values.peek()){
list.add(min.pop());
}
if(!min.isEmpty()){
min.pop();
}
for(int i=list.size()-1;i>=0;i--)
min.push(list.get(i));
}
values.pop();
System.out.println("min after pop -->"+min);
System.out.println("values after pop-->"+values);
}
public int top() {
System.out.println("min on top -->"+min);
System.out.println("values on top-->"+values);
return values.peek();
}
public int getMin() {
System.out.println("min for getMin-->"+min);
System.out.println("values for get min-->"+values);
return min.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/

The wrapper classes like Integer, Long should use equals rather than ==
Use equals here if(values.peek()==min.peek()){
Change it to if(values.peek().equals(min.peek())){
Also min.peek()!=values.peek() to !min.peek().equals(values.peek())
The last thing is you remove the System.out.println lines
One more suggestion would be to not use entire stack for sorted values and recreate it everytime a pop is done on the actual stack.
Rather you should maintain a single min variable and update it if the pop has removed the min item. You can find minimum value using min() method from stream()
You can have a look at the following too
Java: Integer equals vs. ==
How to properly compare two Integers in Java?

Related

Java PriorityQueue with Custom Objects not Sorting Correctly [duplicate]

This question already has answers here:
Why does PriorityQueue.toString return the wrong element order? [duplicate]
(4 answers)
Closed 8 months ago.
I don't completely understand how to use a Java PriorityQueue (max Heap) for custom objects.
I'm working on a LeetCode problem where my code must reorder the words in a sentence by word length. My instinct was that I could use a PriorityQueue to do the work of word-ordering for me. To do that, I thought I could track words with a custom object:
public class word implements Comparable<word>{
public String theWord;
public int len, order;
public word(String w, int order) {
this.theWord = w;
this.order = order;
this.len = w.length();
}
#Override
public int compareTo(word o) {
return this.len - o.len; // sorting behavior controlled here, right???
}
public String toString() {
return this.theWord+"("+this.order+") "; // for troubleshooting
}
}
Then:
public String arrangeWords(String sentence) {
PriorityQueue<word> maxHeap = new PriorityQueue<>(Comparator.naturalOrder());
String[] words = sentence.split(" ");
for( int i=0; i<words.length; i++ ) {
maxHeap.offer( new word(words[i], i) );
}
}
The first sentence I'm using to test is "leetcode is cool". (From the LC post.)
The ordering I'm hoping for is: "is cool leetcode" (shortest-to-longest word order)
But when I run the above code and check the PriorityQueue in the debugger, I see:
is(1) leetcode(0) cool(2)
Sooo... what the heck? I don't understand how this is ordered at all. This is not the original order (indicated by parenthesis), not in length order, not even in alphabetical order. I have no idea how the PriorityQueue is deciding how to order the word objects. I thought that the class word's compareTo() method would force the ordering that I want. (I've seen this with other SO posts.) But not so. Does someone see what I'm going wrong? Thank you.
You inserted them in priority queue. But then you need to poll the queue to get the right order of words.
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll());
}
Also please note the order field won't get altered just because you inserted them in priority queue. It just shows the order in which the word appears in original sentence.
Write that loop after your for loop where you inserted. Then execute again. You will see right order.
PriorityQueue( minHeap) maintains that the top element is of the lowest length . The remaining elements will be in random order. Once you poll the top element, then re-ordering happens( upHeapify -technically ) that makes the smallest from the remaining to become the top element. As already pointed out, you need to poll all the objects and make them part of your sentence.
Also, another way to go about the problem was -> you could have simply used the comparator on the array of String.
class Solution {
public static String arrangeWords(String text) {
String str[] = text.split(" ");
Arrays.sort(str, (a, b) -> a.length() - b.length());
String res = "";
for ( int i = 0; i< str.length; i++)
{
if ( i ==0 )
{
res += str[i].substring(0,1).toUpperCase() + str[i].substring(1) + " ";
}
else{
res += str[i].substring(0,1).toLowerCase() + str[i].substring(1) + " ";
}
}
return res.trim();
}
}

Do empty stacks automatically have a null value?

I'm quite new to java. So I've got some code that is supposed to add files to a stack and compare the stack contents with an existing reference. Here's the class that should create the stack:
public class ArrayStack<T> implements ArrayStackADT<T> {
private T[] stack;
private int top;
// constructor, passes default capacity
public ArrayStack() {
top = -1;
stack = (T[]) new Object[14];
}
// constructor, initializes capacity to stack and top
public ArrayStack(int initialCapacity) {
top = -1;
stack = (T[])new Object[initialCapacity];
}
}
and here is the code that calls the stack:
public static void main(String[] args){
StartSearch path = new StartSearch(args[0]);
int distance = Integer.parseInt(args[1]);
ArrayStack stack = new ArrayStack(); // creates empty stack
MapCell cell = path.targetMap.getStart(); // gets starting cell
stack.push(cell); // pushes starting cell to stack
}
Not sure if I showed enough code, so please let me know if I didn't. I had some push and pop methods to insert and remove stack items, and for each push/pop they'd print "push" + the value:
if (dataItem instanceof MapCell) {
sequence += "push" + ((MapCell)dataItem).getIdentifier();
}
else {
sequence += "push" + dataItem.toString();
}
For some reason though, when I go to print sequence later, it outputs this:
nullpush0push2push3
Instead of what I need it to output:
push0push2push3
Do empty stacks automatically have a null value or something? how do I get rid of the null value at the beginning?
It hasn’t got anything to do with your stack class. It’s how you initialize your String variable. Or perhaps forgot to initialize it? To demonstrate:
String sequence = null;
sequence += "push1";
System.out.println(sequence);
Output is:
nullpush1
Instead initialize sequence to the empty string:
String sequence = "";
push1
Or use a StringBuffer or StringBuilder:
StringBuilder sequence = new StringBuilder();
sequence.append("push1");
System.out.println(sequence);
Output is identical:
push1

Modify the header of the merge method so that it can receive as parameters (and return) stacks that are either array-based or reference-based?

Basically my code works fine but I would like to update it to be more flexible so any ideas on how I can modify the header of the merge method so that it can receive as parameters (and return) stacks that are either array-based or reference-based? I'm gonna post some of the code, if more is necessary then I will update it. Thanks in advance.
/**
* merge: Given two stacks containing Integer objects in increasing order from the bottom up,
* create a third stack such that the Integer objects are in decreasing order from the bottom up.
* If an item appears n times in the two given stacks, it will appear n times in the new stack.
*
* #param s1 the first stack
* #param s2 the second stack
* #return the new stack, with the items from the two given stacks merged.
*/
public static StackReferenceBased merge(StackArrayBased s1, StackReferenceBased s2)
{
StackReferenceBased newStack = new StackReferenceBased();
Integer i1 = new Integer(-1);
Integer i2 = new Integer(-1);
if (!s1.isEmpty())
i1 = (Integer)s1.pop();
if (!s2.isEmpty())
i2 = (Integer)s2.pop();
while (!s1.isEmpty() && !s2.isEmpty()) {
System.out.println("Comparing " + i1 + " and " + i2);
if (i1.compareTo(i2) < 0) {
newStack.push(i2);
//Get next item from second stack
i2 = (Integer)s2.pop();
}
else {
newStack.push(i1);
//Get next item from first stack
i1 = (Integer)s1.pop();
}
}
// At this point, s1 and/or s2 are empty.
if (s1.isEmpty()) {
newStack.push(i2);
while (!s2.isEmpty()) {
newStack.push(s2.pop());
}
}
if (s2.isEmpty()) {
newStack.push(i1);
while (!s1.isEmpty()) {
newStack.push(s1.pop());
}
}
return newStack;
}
Update the signature to accept and return the common interface, StackInterface:
public static StackInterface merge(StackInterface s1, StackInterface s2)

Access the value from list in java [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
This is one of my class
class number11 {
String ab;
int i;
public number11(String ab,int i) {
this.ab=ab;
this.i=i;
}
}
And in main method, I used
List<number11> n1= new ArrayList<number11>();
How can I access the value of integers and String contained in List? I do wish just to print them but to use further.
{Closed ,Thank you all}
Just loop over the list:
for (number11 n : list) {
String ab = n.ab;
int i = n.i;
//print ab and i
}
Note that number11 should be in CamelCase to follow Java's conventions: Number11.
From your question it seems you want list of your objects,
Before continuing, please create getters and setters, I've used them
Also your class name should be camelCase. Number11 is valid but not number11
You can fill the list using
List<number11> list = new ArrayList<number11>();
list.add(new number11("a",1));
list.add(new number11("b",2));
To access the members,
for (number11 n : list) {
String ab = n.getAb();
int i = n.getI();
}
like this
List<number11> n1= new ArrayList<number11>();
for(number11 n:n1){
System.out.println("String value: "+n.ab);
System.out.println("int value: "+n.i);
}
According to better coding standards.Follow the below rules
1.Change you class so that It starts with a camel case.
2.Change variables to private.
3.Add setter and getter methods
Assuming you have added values to the ArrayList you can read values by using code such as n1.get(0).ab or n1.get(0).i.
List l = new ArrayList<number11>();
l.add(new number11("x",1));
l.add(new number11("y",2));
for (number11 element : l) {
System.out.println(element.ab + " "+ element.i);
}
You might first want to add getter methods to your class number11.
e.g
public class number11{
String ab;
int i;
public number11(String ab,int i)
{
this.ab=ab;
this.i=i;
}
public int getI(){
return i;
}
public String getAb(){
return ab;
}
}
You need to obtain a reference to the particular object held inside the ArrayList via the get(index) method where index is the element number starting with 0. Simply call the getter methods to retrieve the values.
e.g
List<number11> n1= new ArrayList<number11>();
//Adding the object
n1.add(new number11("Test", 4));
//Retrieving the object.
number11 inst = n1.get(0);
//Retrieve and print the values
System.out.println(inst.getAb());
System.out.println(inst.getI());
For better convention change your class structure to,
class Number11 {
private String ab;
private int i;
public Number11(String ab,int i) {
this.ab=ab;
this.i=i;
}
public String getAb() {
return ab;
}
public void setAb(String ab) {
this.ab = ab;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
Access in this way.
List<number11> n1= new ArrayList<number11>();
if(n1!=null && n1.size()>0){
for (Number11 n : n1) {
String ab = n.getAb();
int i = n.getI();
//print ab and i
}
}
List<number11> n1= new ArrayList<number11>();
after adding values to this list n1 it will contains number11 type objects from index 0 to n-1, where n is number of element you added to list.
Then you can call what ever object as follows
n1.get(1) // this will return 2nd object in the list
It will contain ab and i
You can call them as follows
n1.get(1).getab // 2nd element ab value in list n1
n1.get(1).i // 2nd element i value in list n1
List Interface allows to:
Positional access — manipulates elements based on their numerical position in the list
MyClass obj = myList.get(24); //--get 25th item of a List<MyClass>--
Iteration access — extends Iterator semantics to take advantage of the list's sequential nature
for(MyClass obj : myList){ //-- go through all items of a List<MyClass> one by one--
int i = obj.someField;
}
Once you have your object, you can access its fields.

How do I remove an element from an array in Java? And how do I skip null array elements?

I'm working through a class assignment and I'm not sure how to remove an element from an array. I've read suggestions to use ArrayUtils or convert the array to a linked list. I'm still very new to Java, so I'm not sure if I actually need to do something like this or if I'm overlooking something that's much simpler. I also need to complete a couple of processes that require skipping all null elements in the array. I don't have a great professor and communication attempts are futile, so I'm hoping someone here can help. My code follows. The relevant bits begin at "public void remove". I'm just posting all of the code in this class to give a fuller picture of what's going on:
public class WatchCollection
{
private Watch watches[]; // an array of references to Watch objects
// watches[i] == null if there is no watch in position i
private int num; // size of the array
private void init(int numberOfWatches) {
watches = new Watch[numberOfWatches];
for (int i=0;i<numberOfWatches;++i)
{
watches[i] = null;
}
num = numberOfWatches;
}
public WatchCollection(int numberOfWatches)
{
init(numberOfWatches);
}
public WatchCollection (Watch w1)
{
init(1);
add(w1);
}
// TODO Define WatchCollection (Watch w1, Watch w2) constructor
public WatchCollection (Watch w1, Watch w2)
{
}
// TODO Define WatchCollection (Watch w1, Watch w2, Watch w3) constructor
public WatchCollection (Watch w1, Watch w2, Watch w3)
{
}
public void add ( Watch w )
{
for(int i=0;i<num;++i)
{
if (watches[i]==null)
{
watches[i]=w;
return;
}
}
}
public void remove ( Watch w )
{
// TODO Write a code that removes Watch w if it is in the array
}
public int size()
{
// TODO Write a code that returns actual number of watches, skip all null array elements
}
public Watch at( int index)
{
// TODO Write a code that returns a watch with the specified index (skip all null array elements)
// TODO Throw an exception if the index is < 0 or >= actual number of watches
// For example, if the array contains w1 w2 null w3 w4
// index 0 -> w1
// index 1 -> w2
// index 2 -> w3
// index 3 -> w4
// index 4 -> an exception
}
public String toString()
{
String str="{\n";
int index=0;
for(int i=0;i<num;++i)
{
if (watches[i]!=null)
{
str+=" " +index++ + ": " +watches[i] + "\n";
}
}
str+=" }";
return str;
}
}
ArrayList is a builtin class that offers indexed access to elements, the ability to remove arbitrary elements, and dynamic expansion.
Since this is a class assignment, I'll just provide the algorithm to implement a remove method in your array (assuming this is an algorithm course):
function remove (Element element)
int index <- -1
for i <- 0 to num - 1
if (array[i] is equals to element) then
index <- i
break
end if
end for
if index > -1 then
for i <- index to num - 2
array[i] <- array[i+1]
end for
num <- num - 1
end if
end function
If this is an exercise about Java programming, it would be better to declare an ArrayList and use it since it already implements all these methods for you.
Without giving you the answer, here is how you could improve when you have.
public class WatchCollection {
private Watch watches[]; // an array of references to Watch objects
// watches[i] == null if there is no watch in position i
private int num = 0; // size of the array used.
public WatchCollection(int numberOfWatches) {
watches = new Watch[numberOfWatches];
}
public WatchCollection(Watch w1) {
this(1);
add(w1);
}
public void add(Watch w) {
if (watches.length == num + 1)
watches = Arrays.copyOf(watches, num*2);
watches[num++] = w;
}
You should try to keep your solution as simple as possible.
Here All you want is dealing with a Watch objects, so you don't need to use array.
Using ArrayList
is the best way to do your work.
This class has methods for accessing indexed elements, removing indexed element, dynamic expansion of the array etc.
The link leads to the official documentation for the ArrayList class.
Use Arraylist instead of array. if you already have an array, convert that to A

Categories