Linked list by reference or by value? - algorithm

Here is the question. Say a linked list is implemented as follows (Java):
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
Consider the linked list:
1 -> 2 -> 3 -> 4
I do something like:
ListNode newHead = head;
newHead = head.next.next;
//Now newHead is pointing to (3) in the linked list.
Now I perform the magic:
newHead.val = 87
The linked list becomes:
1 -> 2 -> 87 -> 4
If I printed head and NOT newHead.
Why is this? I didn't modify anything with head but it still changed?

So you can use this:
Node Class:
public class IntNode {
int value;
IntNode next;
public IntNode(int value) {
this.value = value;
}
}
Singly Linked List Class:
/**
* A singly-linked list of integer values with fast addFirst and addLast methods
*/
public class LinkedIntList {
IntNode first;
IntNode last;
int size;
/**
* Return the integer value at position 'index'
*/
int get(int index) {
return getNode(index).value;
}
/**
* Set the integer value at position 'index' to 'value'
*/
void set(int index, int value) {
getNode(index).value = value;
}
/**
* Returns whether the list is empty (has no values)
*/
boolean isEmpty() {
return size == 0;
}
/**
* Inserts 'value' at position 0 in the list.
*/
void addFirst(int value) {
IntNode newNode = new IntNode(value);
newNode.next = first;
first = newNode;
if(last == null)
last = newNode;
size++;
}
/**
* Appends 'value' at the end of the list.
*/
void addLast(int value) {
IntNode newNode = new IntNode(value);
if(isEmpty())
first = newNode;
else
last.next = newNode;
last = newNode;
size++;
}
/**
* Removes and returns the first value of the list.
*/
int removeFirst() {
if(isEmpty()) {
System.out.println("RemoveFirst() on empty list!");
System.exit(-1);
}
int value = first.value;
if(first == last) {
// List has only one element, so just clear it
clear();
}
else {
first = first.next;
size--;
}
return value;
}
/**
* Removes and returns the last value of the list.
*/
int removeLast() {
if(isEmpty()) {
System.out.println("RemoveLast() on empty list!");
System.exit(-1);
}
int value = last.value;
if(first == last) {
// List has only one element, so just clear it
clear();
}
else {
// List has more than one element
IntNode currentNode = first;
while(currentNode.next != last)
currentNode = currentNode.next;
currentNode.next = null;
last = currentNode;
size--;
}
return value;
}
/**
* Removes all values from the list, making the list empty.
*/
void clear() {
first = last = null;
size = 0;
}
/**
* Returns a new int-array with the same contents as the list.
*/
int[] toArray() {
int[] array = new int[size];
int i = 0;
for(IntNode n = first; n != null; n = n.next, i++)
array[i] = n.value;
return array;
}
/**
* For internal use only.
*/
IntNode getNode(int index) {
if(index < 0 || index >= size) {
System.out.println("GetNode() with invalid index: " + index);
System.exit(-1);
}
IntNode current = first;
for(int i = 0; i < index; i++)
current = current.next;
return current;
}
}
See the comments in the code for description.

Related

Valid Binary Tree

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
static class ReturnData {
public boolean isBST;
public int max;
public int min;
public ReturnData(boolean is, int mi, int ma) {
isBST = is;
min = mi;
max = ma;
}
}
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
ReturnData res = check(root);
if (res == null) {
return true;
}
return res.isBST;
}
private ReturnData check(TreeNode node) {
if (node == null) {
return null;
}
int min = node.val;
int max = node.val;
ReturnData left = check(node.left);
ReturnData right = check(node.right);
if (left != null) {
min = Math.min(min, left.min);
max = Math.max(max, left.max);
}
if (right != null) {
min = Math.min(min, right.min);
max = Math.max(max, right.max);
}
boolean isBST = true;
if (left != null && (!left.isBST || left.min >= node.val)) {
isBST = false;
}
if (right != null && (!right.isBST || right.min <= node.val)) {
isBST = false;
}
return new ReturnData(isBST, min, max);
}
}
I want to ask a LeetCode question, Question 98.
The question wants me to write an algorithm to check whether the given tree is a valid binary tree, so I wrote like this:
I create a constructor to initialize the return type, which contains the current node's value, max, and min value of its subtree.
I want to use recursion to check the validation.
But it doesn't work, I also check the solution but I still don't know why this way didn't work.
Hope someone could give me a hint, thanks.
The problem is in this condition:
left.min >= node.val
You'll want to see whether the maximum in the left tree exceeds the current node's value, so:
left.max >= node.val

Insertion Sort for Singly Linked List [EXTERNAL]

I'm not sure where to start, but this is messy. Basically I need to write an Insertion Sort method for singly linked list - which causes enough problems, because usually for Insertion Sort - you're supposed to go through array/list elements backwards - which implementing into a singly linked list seems pointless, because the point of it - is that you're only capable of going forwards in the list and in addition to that -> I need to execute "swap" operations externally, which I do not completely understand how to perform that while using list structure.
This is my ArrayClass and Swap method that I used:
class MyFileArray : DataArray
{
public MyFileArray(string filename, int n, int seed)
{
double[] data = new double[n];
length = n;
Random rand = new Random(seed);
for (int i = 0; i < length; i++)
{
data[i] = rand.NextDouble();
}
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
for (int j = 0; j < length; j++)
writer.Write(data[j]);
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double this[int index]
{
get
{
Byte[] data = new Byte[8];
fs.Seek(8 * index, SeekOrigin.Begin);
fs.Read(data, 0, 8);
double result = BitConverter.ToDouble(data, 0);
return result;
}
}
public override void Swap(int j, double a)
{
Byte[] data = new Byte[16];
BitConverter.GetBytes(a).CopyTo(data, 0);
fs.Seek(8 * (j + 1), SeekOrigin.Begin);
fs.Write(data, 0, 8);
}
}
And this is my Insertion Sort for array:
public static void InsertionSort(DataArray items)
{
double key;
int j;
for (int i = 1; i < items.Length; i++)
{
key = items[i];
j = i - 1;
while (j >= 0 && items[j] > key)
{
items.Swap(j, items[j]);
j = j - 1;
}
items.Swap(j, key);
}
}
Now I somehow have to do the same exact thing - however using Singly Linked List, I'm given this kind of class to work with (allowed to make changes):
class MyFileList : DataList
{
int prevNode;
int currentNode;
int nextNode;
public MyFileList(string filename, int n, int seed)
{
length = n;
Random rand = new Random(seed);
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
writer.Write(4);
for (int j = 0; j < length; j++)
{
writer.Write(rand.NextDouble());
writer.Write((j + 1) * 12 + 4);
}
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double Head()
{
Byte[] data = new Byte[12];
fs.Seek(0, SeekOrigin.Begin);
fs.Read(data, 0, 4);
currentNode = BitConverter.ToInt32(data, 0);
prevNode = -1;
fs.Seek(currentNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
public override double Next()
{
Byte[] data = new Byte[12];
fs.Seek(nextNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
prevNode = currentNode;
currentNode = nextNode;
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
To be completely honest - I'm not sure neither how I'm supposed to implement Insertion Sort nor How then translate it into an external sort. I've used this code for not external sorting previously:
public override void InsertionSort()
{
sorted = null;
MyLinkedListNode current = headNode;
while (current != null)
{
MyLinkedListNode next = current.nextNode;
sortedInsert(current);
current = next;
}
headNode = sorted;
}
void sortedInsert(MyLinkedListNode newnode)
{
if (sorted == null || sorted.data >= newnode.data)
{
newnode.nextNode = sorted;
sorted = newnode;
}
else
{
MyLinkedListNode current = sorted;
while (current.nextNode != null && current.nextNode.data < newnode.data)
{
current = current.nextNode;
}
newnode.nextNode = current.nextNode;
current.nextNode = newnode;
}
}
So if someone could maybe give some kind of tips/explanations - or maybe if you have ever tried this - code examples how to solve this kind of problem, would be appreciated!
I actually have solved this fairly recently.
Here's the code sample that you can play around with, it should work out of the box.
public class SortLinkedList {
public static class LinkListNode {
private Integer value;
LinkListNode nextNode;
public LinkListNode(Integer value, LinkListNode nextNode) {
this.value = value;
this.nextNode = nextNode;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public LinkListNode getNextNode() {
return nextNode;
}
public void setNextNode(LinkListNode nextNode) {
this.nextNode = nextNode;
}
#Override
public String toString() {
return this.value.toString();
}
}
public static void main(String...args) {
LinkListNode f = new LinkListNode(12, null);
LinkListNode e = new LinkListNode(11, f);
LinkListNode c = new LinkListNode(13, e);
LinkListNode b = new LinkListNode(1, c);
LinkListNode a = new LinkListNode(5, b);
print(sort(a));
}
public static void print(LinkListNode aList) {
LinkListNode iterator = aList;
while (iterator != null) {
System.out.println(iterator.getValue());
iterator = iterator.getNextNode();
}
}
public static LinkListNode sort(LinkListNode aList){
LinkListNode head = new LinkListNode(null, aList);
LinkListNode fringePtr = aList.getNextNode();
LinkListNode ptrBeforeFringe = aList;
LinkListNode findPtr;
LinkListNode prev;
while(fringePtr != null) {
Integer valueToInsert = fringePtr.getValue();
findPtr = head.getNextNode();
prev = head;
while(findPtr != fringePtr) {
System.out.println("fringe=" + fringePtr);
System.out.println(findPtr);
if (valueToInsert <= findPtr.getValue()) {
LinkListNode tmpNode = fringePtr.getNextNode();
fringePtr.setNextNode(findPtr);
prev.setNextNode(fringePtr);
ptrBeforeFringe.setNextNode(tmpNode);
fringePtr = ptrBeforeFringe;
break;
}
findPtr = findPtr.getNextNode();
prev = prev.getNextNode();
}
fringePtr = fringePtr.getNextNode();
if (ptrBeforeFringe.getNextNode() != fringePtr) {
ptrBeforeFringe = ptrBeforeFringe.getNextNode();
}
}
return head.getNextNode();
}
}
From a high level, what you are doing is you are keeping track of a fringe ptr, and you are inserting a node s.t. the it is in the correct spot in the corresponding sublist.
For instance, suppose I have this LL.
3->2->5->4
The first iteration, I have fringePtr at 2, and I want to insert 2 somewhere in the sublist that's before the fringe ptr, so I basically traverse starting from head going to the fringe ptr until the value is less than the current value. I also have a previous keeping track of the previous ptr (to account for null, I have a sentinel node at the start of my traversal so I can insert it at the head).
Then, when I see that it's less than the current, I know I need to insert it next to the previous, so I have to:
use a temporary ptr to keep track of my previous's current next.
bind previuos's next to my toInsert node.
bind my toInsert node's next to my temp node.
Then, to continue, you just advance your fringe ptr and try again, basically building up a sublist that is sorted as you move along until fringe hits the end.
i.e. the iterations will look like
1. 3->2->5->4
^
2. 2->3->5->4
^
3. 2->3->5->4
^
4. 2->3->4->5 FIN.

Finding and removing the last occurrence of an element in a (singly) linked list with only one traversal

Is it possible to find the last occurrence of an element (for example, an integer) and remove this node with only one (forward) traversal through the list?
Yes.
Simply remember the previous entry every time you find the value you're searching for on the traversal. When the traversal is complete, the last entry remembered will have a link to the entry to be removed, and that is sufficient to do the removal.
public void DeleteLastOccurenceOfKey(Node head, int key)
{
Node current=head;
Node prev=null;
Node temp=null;
while(current!=null)
{
if(current.next!=null && current.next.data==key)
{
prev=current;
temp=current.next;
}
current=current.next;
}
prev.next=temp.next;
}
DeleteLastOccurenceOfKey(head,25);
I/P:5 10 15 25 35 25 40
O/P:5 10 15 25 35 40
/*
* Delete last occurrence of an item from linked list
* Given a liked list and a key to be deleted. Delete last occurrence of key
* from linked. The list may have duplicates.
*
* Examples:
*
* Input: 1->2->3->5->2->10, key = 2`enter code here`
* Output: 1->2->3->5->10
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct list_ list;
struct list_ {
int d;
list *next;
};
void insert (list **head, int d) {
list *tmp = (list *)malloc(sizeof(list));
assert(tmp);
tmp->d = d;
tmp->next = *head;
*head = tmp;
}
void printL (list *p) {
while (p) {
printf (" %d ", p->d);
p = p->next;
}
printf ("\n");
}
void deletlastOccurence (list **head, int d) {
list *cur = *head;
list *prev = NULL;
list *match = NULL;
if (cur == NULL) {
printf ("list is empty\n");
return;
}
/*
* Special case when there only ONE NODE
* in the LIST
*/
if (cur->next == NULL) {
if (cur->d == d) {
printf ("Deleted one node %d\n", cur->d);
free(cur);
*head = NULL;
} else {
printf(" No match\n");
}
return;
}
/*
* Keep track of previous node
*/
while (cur && cur->next) {
if (cur->next->d == d) {
prev = cur;
match = cur->next;
}
cur = cur->next;
}
if (prev){
prev->next = match->next;
printf ("Delete %d\n", match->d);
free (match);
} else {
/*
* Special case when the last node is
* on the head itself
*/
if ((*head)->d == d) {
cur = *head;
*head = cur->next;
printf("element is at head Delete %d\n", cur->d);
free (cur);
} else {
printf ("No match\n");
}
}
printL(*head);
}
int main (int argc , char *argv) {
list *h = NULL;
insert(&h, 1);
insert(&h, 2);
insert(&h, 3);
insert(&h, 4);
insert(&h, 5);
insert(&h, 2);
insert(&h, 1);
insert(&h, 6);
printL(h);
deletlastOccurence(&h, 6);
deletlastOccurence(&h, 2);
}
public void deleteLastOccurence(int value) {
Element cur = this.head;
Element prev = null;
Element tmp = null;
if(this.head == null)
return;
if(this.head.data == value) {
this.head = null;
return;
}
while(cur != null) {
if(cur.next != null && cur.next.data == value) {
prev = cur;
tmp = cur.next;
}
cur = cur.next;
}
prev.next = tmp.next;
}

Add two big numbers represented as linked lists without reversing the linked lists

Suppose you have 2 big numbers represented as linked lists, how do you add them and store the result in a separate linked list.
eg
a = 2 -> 1 -> 7
b = 3 -> 4
result = 2 -> 5 -> 1
Can you add them without reversing the linked lists
Pseudocode:
Step 1. Traverse the linked lists and push the elements in two different stacks
Step 2. Pop the top elements from both the stacks
Step 3. Add the elements (+ any carry from previous additions) and store the carry in a temp variable
Step 4. Create a node with the sum and insert it into beginning of the result list
I think this's something beyond context but can be very performance incentive for the person who originally posted this question.
So here's a recommendation:
instead of using every node as a single digit of the number, use each node to store a large number(close to the size of integer) and if the highest possible number you chose to store in each node be x(your case 9) then you can view your number as a representation in base x+1.
where each digit is a number between 0 and x.
This would give you significant performance gain as the algorithm would run in O(log n) time and require the same number of nodes as against O(n) in your case , n being the number of decimal digits of the larger of two addends.
Typically for the ease of your algorithm, you can choose a power of 10 as the base which fits in the range of your integer.
For example if your number be 1234567890987654321 and you want to store it in linked list choosing the base to be 10^8 then your representation should look like:
87654321-> 4567890 -> 123(little endian)
Here's my hacky attempt in Java that runs in about O(max(len(a),len(b))). I've provided a complete sample with a very simple singly linked list implementation. It's quite late here so the code is not as nice as I'd like - sorry!
This code assumes:
That the length of the lists is known
Singly linked list
Dealing with integer data
It uses recursion to propagate the sums and carry for each digit, and sums left to right. The lists are never reversed - sums are performed left to right, and carry propagates up the recursive stack. It could be unrolled in an iterative solution, but I won't worry about that.
public class LinkedListSum {
static class LLNode {
int value;
LLNode next;
public LLNode(int value){
this.value = value;
}
public int length(){
LLNode node = this;
int count = 0;
do {
count++;
} while((node = node.next) != null);
return count;
}
public List<Integer> toList(){
List<Integer> res = new ArrayList<Integer>();
LLNode node = this;
while(node != null){
res.add(node.value);
node = node.next;
}
return res;
}
}
public static void main(String[] argc){
LLNode list_a = fromArray(new int[]{4,7,4,7});
LLNode list_b = fromArray(new int[]{5,3,7,4,7,4});
System.out.println("Sum: " + sum(list_a, list_b).toList());
}
private static LLNode fromArray(int[] arr){
LLNode res = new LLNode(0);
LLNode current = res;
for(int i = 0; i < arr.length; i++){
LLNode node = new LLNode(arr[i]);
current.next = node;
current = node;
}
return res.next;
}
private static LLNode sum(LLNode list_1, LLNode list_2){
LLNode longer;
LLNode shorter;
if(list_1.length() >= list_2.length()){
longer = list_1;
shorter = list_2;
} else {
longer = list_2;
shorter = list_1;
}
// Pad short to same length as long
int diff = longer.length() - shorter.length();
for(int i = 0; i < diff; i++){
LLNode temp = new LLNode(0);
temp.next = shorter;
shorter = temp;
}
System.out.println("Longer: " + longer.toList());
System.out.println("Shorter: " + shorter.toList());
return sum_same_length(new LLNode(0), null, longer, shorter);
}
private static LLNode sum_same_length(LLNode current, LLNode previous, LLNode longerList, LLNode shorterList){
LLNode result = current;
if(longerList == null){
previous.next = null;
return result;
}
int sum = longerList.value + shorterList.value;
int first_value = sum % 10;
int first_carry = sum / 10;
current.value = first_value;
// Propagate the carry backwards - increase next multiple of 10 if necessary
LLNode root = propagateCarry(current,previous,first_carry);
current.next = new LLNode(0);
sum_same_length(current.next, current, longerList.next, shorterList.next);
// Propagate the carry backwards - increase next multiple of 10 if necessary:
// The current value could have been increased during the recursive call
int second_value = current.value % 10;
int second_carry = current.value / 10;
current.value = second_value;
root = propagateCarry(current,previous,second_carry);
if(root != null) result = root;
return result;
}
// Returns the new root of the linked list if one had to be added (due to carry)
private static LLNode propagateCarry(LLNode current, LLNode previous, int carry){
LLNode result = null;
if(carry != 0){
if(previous != null){
previous.value += carry;
} else {
LLNode first = new LLNode(carry);
first.next = current;
result = first;
}
}
return result;
}
}
Here is a pseudo code.
list *add (list *l1, list *l2)
{
node *l3, l3_old;
while (l1 != NULL)
{
stack1.push (l1);
l1 = l1->next;
}
while (l2 != NULL)
{
stack2.push (l2);
l2 = l2->next;
}
l3_old = NULL;
while (!stack1.isempty () && !stack2.isempty ()) // at least one stack is not empty
{
l3 = get_new_node ();
l1 = stack1.pop ();
l2 = stack2.pop ();
l3->val = l1->val + l2->val;
if (l3_old != NULL)
{
l3->val = l3->val + (int)l3_old/10;
l3_old->val %= 10;
}
l3->next = l3_old;
l3_old = l3;
}
while (!stack1.isempty ())
{
l1 = stack1.pop ();
l3 = get_new_node ();
l3->val = l1->val + (int)l3_old->val/10;
l3_old->val %= 10;
l3->next = l3_old;
l3_old = l3;
}
while (!stack2.isempty ())
{
l2 = stack2.pop ();
l3 = get_new_node ();
l3->val = l2->val + (int)l3_old->val/10;
l3_old->val %= 10;
l3->next = l3_old;
l3_old = l3;
}
return l3;
}
Here is my attempt, using the two linked lists and returning the sum as a new list using recursion.
public class SumList {
int[] a1= {7,3,2,8};
int[] a2= {4,6,8,4};
LinkedList l1= new LinkedList(a1);
LinkedList l2= new LinkedList(a2);
Node num1= l1.createList();
Node num2= l2.createList();
Node result;
public static void main(String[] args) {
SumList sl= new SumList();
int c= sl.sum(sl.num1, sl.num2);
if(c>0) {
Node temp= new Node(c);
temp.next= sl.result;
sl.result= temp;
}
while(sl.result != null){
System.out.print(sl.result.data);
sl.result= sl.result.next;
}
}
int sum(Node n1, Node n2) {
if(n1==null || n2==null)
return 0;
int a1= this.getSize(n1);
int a2= this.getSize(n2);
int carry, s= 0;
if(a1>a2) {
carry= sum(n1.next, n2);
s= n1.data+carry;
}
else if(a2>a1) {
carry= sum(n1, n2.next);
s= n2.data+carry;
}
else {
carry= sum(n1.next, n2.next);
s= n1.data+n2.data+carry;
}
carry= s/10;
s=s%10;
Node temp= new Node(s);
temp.next= result;
result= temp;
return carry;
}
int getSize(Node n) {
int count =0;
while(n!=null) {
n=n.next;
count++;
}
return count;
}
}
// A recursive program to add two linked lists
#include <stdio.h>
#include <stdlib.h>
// A linked List Node
struct node
{
int data;
struct node* next;
};
typedef struct node node;
/* A utility function to insert a node at the beginning of linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* A utility function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
printf("\n");
}
// A utility function to swap two pointers
void swapPointer( node** a, node** b )
{
node* t = *a;
*a = *b;
*b = t;
}
/* A utility function to get size of linked list */
int getSize(struct node *node)
{
int size = 0;
while (node != NULL)
{
node = node->next;
size++;
}
return size;
}
// Adds two linked lists of same size represented by head1 and head2 and returns
// head of the resultant linked list. Carry is propagated while returning from
// the recursion
node* addSameSize(node* head1, node* head2, int* carry)
{
// Since the function assumes linked lists are of same size,
// check any of the two head pointers
if (head1 == NULL)
return NULL;
int sum;
// Allocate memory for sum node of current two nodes
node* result = (node *)malloc(sizeof(node));
// Recursively add remaining nodes and get the carry
result->next = addSameSize(head1->next, head2->next, carry);
// add digits of current nodes and propagated carry
sum = head1->data + head2->data + *carry;
*carry = sum / 10;
sum = sum % 10;
// Assigne the sum to current node of resultant list
result->data = sum;
return result;
}
// This function is called after the smaller list is added to the bigger
// lists's sublist of same size. Once the right sublist is added, the carry
// must be added toe left side of larger list to get the final result.
void addCarryToRemaining(node* head1, node* cur, int* carry, node** result)
{
int sum;
// If diff. number of nodes are not traversed, add carry
if (head1 != cur)
{
addCarryToRemaining(head1->next, cur, carry, result);
sum = head1->data + *carry;
*carry = sum/10;
sum %= 10;
// add this node to the front of the result
push(result, sum);
}
}
// The main function that adds two linked lists represented by head1 and head2.
// The sum of two lists is stored in a list referred by result
void addList(node* head1, node* head2, node** result)
{
node *cur;
// first list is empty
if (head1 == NULL)
{
*result = head2;
return;
}
// second list is empty
else if (head2 == NULL)
{
*result = head1;
return;
}
int size1 = getSize(head1);
int size2 = getSize(head2) ;
int carry = 0;
// Add same size lists
if (size1 == size2)
*result = addSameSize(head1, head2, &carry);
else
{
int diff = abs(size1 - size2);
// First list should always be larger than second list.
// If not, swap pointers
if (size1 < size2)
swapPointer(&head1, &head2);
// move diff. number of nodes in first list
for (cur = head1; diff--; cur = cur->next);
// get addition of same size lists
*result = addSameSize(cur, head2, &carry);
// get addition of remaining first list and carry
addCarryToRemaining(head1, cur, &carry, result);
}
// if some carry is still there, add a new node to the fron of
// the result list. e.g. 999 and 87
if (carry)
push(result, carry);
}
// Driver program to test above functions
int main()
{
node *head1 = NULL, *head2 = NULL, *result = NULL;
int arr1[] = {9, 9, 9};
int arr2[] = {1, 8};
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
// Create first list as 9->9->9
int i;
for (i = size1-1; i >= 0; --i)
push(&head1, arr1[i]);
// Create second list as 1->8
for (i = size2-1; i >= 0; --i)
push(&head2, arr2[i]);
addList(head1, head2, &result);
printList(result);
return 0;
}
1.First traverse the two lists and find the lengths of the two lists(Let m,n be the lengths).
2.Traverse n-m nodes in the longer list and set 'prt1' to the current node and 'ptr2' to beginning of the other list.
3.Now call the following recursive function with flag set to zero:
void add(node* ptr1,node* ptr2){
if(ptr1==NULL)
return;
add(ptr1->next,ptr2->next);
insertAtBegin(ptr1->data+ptr2->data+flag);
flag=(ptr1->data+ptr2->data)%10;
}
4.Now you need to add the remaining n-m nodes at the beginning of your target list, you can do it directly using a loop. Please note that for the last element in the loop you need to add the flag returned by the add() function as there might be a carry.
If your question is without using recursion:
1.Repeat the first two steps, then create your target list initalising every elements with '0'(make sure that the length of the list is accurate).
2.Traverse the two lists along with your target list(a step behind).If you find sum of two nodes greater than 10, make the value in the target list as '1'.
3.With the above step you took care of the carry. Now in one more pass just add the two nodes modulo 10 and add this value in the corresponding node of the target list.
without using stack .....
simply store the content of link list in array and perform addition and and then again put addition into link list
code :
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
int value;
struct node *next;
}node;
int main()
{
printf("\nEnter the number 1 : ");
int ch;
node *p=NULL;
node *k=NULL;
printf("\nEnter the number of digit : ");
scanf("%d",&ch);
int i=0;
while(ch!=i)
{
i++;
node *q=NULL;
int a=0;
q=(node *)malloc(sizeof(node));
printf("\nEnter value : ");
scanf("%d",&a);
q->value=a;
if(p==NULL)
{
q->next=NULL;
p=q;
k=p;
}
else
{
q->next=NULL;
p->next=q;
p=q;
}
}
printf("\nEnter the number 2 : ");
int ch1;
node *p1=NULL;
node *k1=NULL;
int i1=0;
printf("\nEnter the number of digit : ");
scanf("%d",&ch1);
while(ch1!=i1)
{
i1++;
node *q1=NULL;
int a1=0;
q1=(node *)malloc(sizeof(node));
printf("\nEnter value : ");
scanf("%d",&a1);
q1->value=a1;
if(p1==NULL)
{
q1->next=NULL;
p1=q1;
k1=p1;
}
else
{
q1->next=NULL;
p1->next=q1;
p1=q1;
}
}
printf("\n\t");
int arr1[100];
int arr1_ptr=0;
while(k != NULL )
{
printf("%d\t",k->value);
arr1[arr1_ptr++]=k->value;
k=k->next;
}
printf("\n\t");
int arr2[100];
int arr2_ptr=0;
while(k1 != NULL )
{
printf("%d\t",k1->value);
arr2[arr2_ptr++]=k1->value;
k1=k1->next;
}
//addition logic ...
int result[100]={0};
int result_ptr=0;
int loop_ptr=0;
int carry=0;
arr1_ptr--;
arr2_ptr--;
if(arr1_ptr>arr2_ptr)
loop_ptr=arr1_ptr+1;
else
loop_ptr=arr2_ptr+1;
for(int i = loop_ptr ; i >= 0;i--)
{
if(arr1_ptr >= 0 && arr2_ptr >= 0)
{
if( (arr1[arr1_ptr] + arr2[arr2_ptr] + carry ) > 9 )
{
result[i]=((arr1[arr1_ptr] + arr2[arr2_ptr]+carry) % 10 );
carry = ((arr1[arr1_ptr--] + arr2[arr2_ptr--]+carry ) / 10 ) ;
}
else
{
result[i]=(arr1[arr1_ptr--] + arr2[arr2_ptr--] + carry );
carry = 0 ;
}
}
else if( !(arr1_ptr < 0 ) || !( arr2_ptr < 0 ) )
{
if( arr1_ptr < 0)
result[i]=arr2[arr2_ptr--]+carry;
else
result[i]=arr1[arr1_ptr--]+carry;
}
else
result[i]=carry;
}
/*printf("\n");
for(int i=0;i<loop_ptr+1;i++)
printf("%d\t",result[i]);
*/
node *k2=NULL,*p2=NULL;
for(int i=0;i<loop_ptr+1;i++)
{
node *q2=NULL;
q2=(node *)malloc(sizeof(node));
q2->value=result[i];
if(p2==NULL)
{
q2->next=NULL;
p2=q2;
k2=p2;
}
else
{
q2->next=NULL;
p2->next=q2;
p2=q2;
}
}
printf("\n");
while(k2 != NULL )
{
printf("%d\t",k2->value);
k2=k2->next;
}
return 0;
}
We can add them by using recursion. Assume the question is defined as follows: we have lists l1 and l2 and we want to add them by storing the result in l1. For simplicity assume that both lists have the same length (the code can be easily modified to work for different lengths). Here is my working Java solution:
private static ListNode add(ListNode l1, ListNode l2){
if(l1 == null)
return l2;
if(l2 == null)
return l1;
int[] carry = new int[1];
add(l1, l2, carry);
if(carry[0] != 0){
ListNode newHead = new ListNode(carry[0]);
newHead.next = l1;
return newHead;
}
return l1;
}
private static void add(ListNode l1, ListNode l2, int[] carry) {
if(l1.next == null && l2.next == null){
carry[0] = l1.val + l2.val;
l1.val = carry[0]%10;
carry[0] /= 10;
return;
}
add(l1.next, l2.next, carry);
carry[0] += l1.val + l2.val;
l1.val = carry[0]%10;
carry[0] /= 10;
}
Input : List a , List b
Output : List c
Most approaches here require extra space for List a and List b. This can be removed.
Reverse List a and List b so that they are represented in the reverse order (i.e., tail as head and all the links reversed) with constant space of O(1).
Then add the lists efficiently by traversing through both of them simultaneously and maintaining a carry.
Reverse List a and List b if required
Try this
/* No Recursion, No Reversal - Java */
import java.util.*;
class LinkedListAddMSB
{
static LinkedList<Integer> addList(LinkedList<Integer> num1, LinkedList<Integer> num2)
{
LinkedList<Integer> res = new LinkedList<Integer>();
LinkedList<Integer> shorter = new LinkedList<Integer>();
LinkedList<Integer> longer = new LinkedList<Integer>();
int carry = 0;
int maxlen,minlen;
if(num1.size() >= num2.size())
{
maxlen = num1.size();
minlen = num2.size();
shorter = num2;
longer = num1;
}
else
{
maxlen = num2.size();
minlen = num1.size();
shorter = num1;
longer = num2;
}
//Pad shorter list to same length by adding preceeding 0
int diff = maxlen - minlen;
for(int i=0; i<diff; i++)
{
shorter.addFirst(0);
}
for(int i=maxlen-1; i>=0; i--)
{
int temp1 = longer.get(i);
int temp2 = shorter.get(i);
int temp3 = temp1 + temp2 + carry;
carry = 0;
if(temp3 >= 10)
{
carry = (temp3/10)%10;
temp3 = temp3%10;
}
res.addFirst(temp3);
}
if(carry > 0)
res.addFirst(carry);
return res;
}
public static void main(String args[])
{
LinkedList<Integer> num1 = new LinkedList<Integer>();
LinkedList<Integer> num2 = new LinkedList<Integer>();
LinkedList<Integer> res = new LinkedList<Integer>();
//64957
num1.add(6);
num1.add(4);
num1.add(9);
num1.add(5);
num1.add(7);
System.out.println("First Number: " + num1);
//48
num2.add(4);
num2.add(8);
System.out.println("First Number: " + num2);
res = addList(num1,num2);
System.out.println("Result: " + res);
}
}
/* this baby does not reverse the list
** , it does use recursion, and it uses a scratch array */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list {
struct list *next;
unsigned value;
};
unsigned recurse( char target[], struct list *lp);
struct list * grab ( char buff[], size_t len);
unsigned recurse( char target[], struct list *lp)
{
unsigned pos;
if (!lp) return 0;
pos = recurse (target, lp->next);
/* We should do a bounds check target[] here */
target[pos] += lp->value;
if (target[pos] >= 10) {
target[pos+1] += target[pos] / 10;
target[pos] %= 10;
}
return 1+pos;
}
struct list * grab ( char *buff, size_t len)
{
size_t idx;
struct list *ret, **hnd;
/* Skip prefix of all zeros. */
for (idx=len; idx--; ) {
if (buff [idx] ) break;
}
if (idx >= len) return NULL;
/* Build the result chain. Buffer has it's LSB at index=0,
** but we just found the MSB at index=idx.
*/
ret = NULL; hnd = &ret;
do {
*hnd = malloc (sizeof **hnd);
(*hnd)->value = buff[idx];
(*hnd)->next = NULL;
hnd = &(*hnd)->next;
} while (idx--);
return ret;
}
int main (void)
{
char array[10];
struct list a[] = { {NULL, 2} , {NULL, 1} , {NULL, 7} };
struct list b[] = { {NULL, 3} , {NULL, 4} };
struct list *result;
a[0].next = &a[1]; a[1].next = &a[2];
b[0].next = &b[1];
memset(array, 0 , sizeof array );
(void) recurse ( array, a);
(void) recurse ( array, b);
result = grab ( array, sizeof array );
for ( ; result; result = result->next ) {
printf( "-> %u" , result->value );
}
printf( "\n" );
return 0;
}
Final version (no list reversal, no recursion):
#include <stdio.h>
#include <stdlib.h>
struct list {
struct list *nxt;
unsigned val;
};
struct list *sumlist(struct list *l, struct list *r);
int difflen(struct list *l, struct list *r);
struct list *sumlist(struct list *l, struct list *r)
{
int carry,diff;
struct list *result= NULL, **pp = &result;
/* If the lists have different lengths,
** the sum will start with the prefix of the longest list
*/
for (diff = difflen(l, r); diff; diff += (diff > 0) ? -1 : 1) {
*pp = malloc (sizeof **pp) ;
(*pp)->nxt = NULL;
if (diff > 0) { (*pp)->val = l->val; l= l->nxt; }
else { (*pp)->val = r->val; r= r->nxt; }
pp = &(*pp)->nxt ;
}
/* Do the summing.
** whenever the sum is ten or larger we increment a carry counter
*/
for (carry=0; l && r; l=l->nxt, r=r->nxt) {
*pp = malloc (sizeof **pp) ;
(*pp)->nxt = NULL;
(*pp)->val = l->val + r->val;
if ((*pp)->val > 9) carry++;
pp = &(*pp)->nxt ;
}
/* While there are any carries, we will need to propagate them.
** Because we cannot reverse the list (or walk it backward),
** this has to be done iteratively.
** Special case: if the first digit needs a carry,
** we have to insert a node in front of it
*/
for (diff =0 ;carry; carry = diff) {
struct list *tmp;
if (result && result->val > 9) {
tmp = malloc(sizeof *tmp);
tmp->nxt = result;
tmp->val = 0;
result = tmp;
}
diff=0;
for (tmp=result; tmp ; tmp= tmp->nxt) {
if (tmp->nxt && tmp->nxt->val > 9) {
tmp->val += tmp->nxt->val/10;
tmp->nxt->val %= 10; }
if (tmp->val > 9) diff++;
}
}
return result;
}
int difflen(struct list *l, struct list *r)
{
int diff;
for (diff=0; l || r; l = (l)?l->nxt:l, r = (r)?r->nxt:r ) {
if (l && r) continue;
if (l) diff++; else diff--;
}
return diff;
}
int main (void)
{
struct list one[] = { {one+1, 2} , {one+2, 6} , {NULL, 7} };
struct list two[] = { {two+1, 7} , {two+2, 3} , {NULL, 4} };
struct list *result;
result = sumlist(one, two);
for ( ; result; result = result->nxt ) {
printf( "-> %u" , result->val );
}
printf( ";\n" );
return 0;
}
In java i will do it this way
public class LLSum {
public static void main(String[] args) {
LinkedList<Integer> ll1 = new LinkedList<Integer>();
LinkedList<Integer> ll2 = new LinkedList<Integer>();
ll1.add(7);
ll1.add(5);
ll1.add(9);
ll1.add(4);
ll1.add(6);
ll2.add(8);
ll2.add(4);
System.out.println(addLists(ll1,ll2));
}
public static LinkedList<Integer> addLists(LinkedList<Integer> ll1, LinkedList<Integer> ll2){
LinkedList<Integer> finalList = null;
int num1 = makeNum(ll1);
int num2 = makeNum(ll2);
finalList = makeList(num1+num2);
return finalList;
}
private static LinkedList<Integer> makeList(int num) {
LinkedList<Integer> newList = new LinkedList<Integer>();
int temp=1;
while(num!=0){
temp = num%10;
newList.add(temp);
num = num/10;
}
return newList;
}
private static int makeNum(LinkedList<Integer> ll) {
int finalNum = 0;
for(int i=0;i<ll.size();i++){
finalNum += ll.get(i) * Math.pow(10,i);
}
return finalNum;
}
}
Here is my first try:
public class addTwo {
public static void main(String args[]){
LinkedListNode m =new LinkedListNode(3);
LinkedListNode n = new LinkedListNode(5);
m.appendNew(1);
m.appendNew(5);
m.appendNew(5);
n.appendNew(9);
n.appendNew(2);
n.appendNew(5);
n.appendNew(9);
n.appendNew(9 );
m.print();
n.print();
LinkedListNode add=addTwo(m,n);
add.print();
}
static LinkedListNode addTwo(LinkedListNode m,LinkedListNode n){
LinkedListNode result;
boolean flag =false;
int num;
num=m.data+n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result = new LinkedListNode(num%10);
while(m.link!=null && n.link!=null){
m=m.link;
n=n.link;
num=m.data+n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
if(m.link==null && n.link==null){
if(flag)
result.appendNew(1);
flag=false;
}else if(m.link!=null){
while(m.link !=null){
m=m.link;
num=m.data;
num=m.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
}else{
while(n.link !=null){
n=n.link;
num=n.data;
num=n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
}
if(flag){
result.appendNew(1);
}
return result;
}
class LinkedListNode {
public int data;
public LinkedListNode link;
public LinkedListNode(){System.out.println(this+":"+this.link+":"+this.data);}
public LinkedListNode(int data){
this.data=data;
}
void appendNew(int data){
if(this==null){
System.out.println("this is null");
LinkedListNode newNode = new LinkedListNode(data);
}
LinkedListNode newNode = new LinkedListNode(data);
LinkedListNode prev =this;
while(prev.link!=null){
prev = prev.link;
}
prev.link=newNode;
}
void print(){
LinkedListNode n=this;
while(n.link!=null){
System.out.print(n.data +"->");
n = n.link;
}
System.out.println(n.data);
}
}
result is:
3->1->5->5
5->9->2->5->9->9
8->0->8->0->0->0->1
My recursive Java implementation:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return addTwoNumbers(l1, l2, 0);
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2, int carryOver) {
int result;
ListNode next = null;
if (l1 == null && l2 == null) {
if (carryOver > 0) {
return new ListNode(carryOver);
} else {
return null;
}
} else if (l1 == null && l2 != null) {
result = l2.val + carryOver;
next = addTwoNumbers(null, l2.next, result / 10);
} else if (l1 != null && l2 == null){
result = l1.val + carryOver;
next = addTwoNumbers(l1.next, null, result / 10);
} else {
result = l1.val + l2.val + carryOver;
next = addTwoNumbers(l1.next, l2.next, result / 10);
}
ListNode node = new ListNode(result % 10);
node.next = next;
return node;
}
}
Hope that helps.
/* spoiler: just plain recursion will do */
#include <stdio.h>
struct list {
struct list *next;
unsigned value;
};
struct list a[] = { {NULL, 2} , {NULL, 1} , {NULL, 7} };
struct list b[] = { {NULL, 3} , {NULL, 4} };
unsigned recurse( unsigned * target, struct list *lp);
unsigned recurse( unsigned * target, struct list *lp)
{
unsigned fact;
if (!lp) return 1;
fact = recurse (target, lp->next);
*target += fact * lp->value;
return 10*fact;
}
int main (void)
{
unsigned result=0;
/* set up the links */
a[0].next = &a[1];
a[1].next = &a[2];
b[0].next = &b[1];
(void) recurse ( &result, a);
(void) recurse ( &result, b);
printf( "Result = %u\n" , result );
return 0;
}

design a stack such that getMinimum( ) should be O(1)

This is an interview question.
You need to design a stack which holds an integer value such that getMinimum() function should return the minimum element in the stack.
For example:
case #1
5 ← TOP
1
4
6
2
When getMinimum() is called it should return 1, which is the minimum element in the stack.
case #2
stack.pop()
stack.pop()
Note: Both 5 and 1 are popped out of the stack.
So after this, the stack looks like
4 ← TOP
6
2
When getMinimum() is called it should return 2 which is the minimum in the stack.
Constraints:
getMinimum should return the minimum value in O(1)
Space constraint also has to be considered while designing it and if you use extra space, it should be of constant space.
EDIT: This fails the "constant space" constraint - it basically doubles the space required. I very much doubt that there's a solution which doesn't do that though, without wrecking the runtime complexity somewhere (e.g. making push/pop O(n)). Note that this doesn't change the complexity of the space required, e.g. if you've got a stack with O(n) space requirements, this will still be O(n) just with a different constant factor.
Non-constant-space solution
Keep a "duplicate" stack of "minimum of all values lower in the stack". When you pop the main stack, pop the min stack too. When you push the main stack, push either the new element or the current min, whichever is lower. getMinimum() is then implemented as just minStack.peek().
So using your example, we'd have:
Real stack Min stack
5 --> TOP 1
1 1
4 2
6 2
2 2
After popping twice you get:
Real stack Min stack
4 2
6 2
2 2
Please let me know if this isn't enough information. It's simple when you grok it, but it might take a bit of head-scratching at first :)
(The downside of course is that it doubles the space requirement. Execution time doesn't suffer significantly though - i.e. it's still the same complexity.)
EDIT: There's a variation which is slightly more fiddly, but has better space in general. We still have the min stack, but we only pop from it when the value we pop from the main stack is equal to the one on the min stack. We only push to the min stack when the value being pushed onto the main stack is less than or equal to the current min value. This allows duplicate min values. getMinimum() is still just a peek operation. For example, taking the original version and pushing 1 again, we'd get:
Real stack Min stack
1 --> TOP 1
5 1
1 2
4
6
2
Popping from the above pops from both stacks because 1 == 1, leaving:
Real stack Min stack
5 --> TOP 1
1 2
4
6
2
Popping again only pops from the main stack, because 5 > 1:
Real stack Min stack
1 1
4 2
6
2
Popping again pops both stacks because 1 == 1:
Real stack Min stack
4 2
6
2
This ends up with the same worst case space complexity (double the original stack) but much better space usage if we rarely get a "new minimum or equal".
EDIT: Here's an implementation of Pete's evil scheme. I haven't tested it thoroughly, but I think it's okay :)
using System.Collections.Generic;
public class FastMinStack<T>
{
private readonly Stack<T> stack = new Stack<T>();
// Could pass this in to the constructor
private readonly IComparer<T> comparer = Comparer<T>.Default;
private T currentMin;
public T Minimum
{
get { return currentMin; }
}
public void Push(T element)
{
if (stack.Count == 0 ||
comparer.Compare(element, currentMin) <= 0)
{
stack.Push(currentMin);
stack.Push(element);
currentMin = element;
}
else
{
stack.Push(element);
}
}
public T Pop()
{
T ret = stack.Pop();
if (comparer.Compare(ret, currentMin) == 0)
{
currentMin = stack.Pop();
}
return ret;
}
}
Add a field to hold the minimum value and update it during Pop() and Push(). That way getMinimum() will be O(1), but Pop() and Push() will have to do a little more work.
If minimum value is popped, Pop() will be O(n), otherwise they will still both be O(1). When resizing Push() becomes O(n) as per the Stack implementation.
Here's a quick implementation
public sealed class MinStack {
private int MinimumValue;
private readonly Stack<int> Stack = new Stack<int>();
public int GetMinimum() {
if (IsEmpty) {
throw new InvalidOperationException("Stack is empty");
}
return MinimumValue;
}
public int Pop() {
var value = Stack.Pop();
if (value == MinimumValue) {
MinimumValue = Stack.Min();
}
return value;
}
public void Push(int value) {
if (IsEmpty || value < MinimumValue) {
MinimumValue = value;
}
Stack.Push(value);
}
private bool IsEmpty { get { return Stack.Count() == 0; } }
}
public class StackWithMin {
int min;
int size;
int[] data = new int[1024];
public void push ( int val ) {
if ( size == 0 ) {
data[size] = val;
min = val;
} else if ( val < min) {
data[size] = 2 * val - min;
min = val;
assert (data[size] < min);
} else {
data[size] = val;
}
++size;
// check size and grow array
}
public int getMin () {
return min;
}
public int pop () {
--size;
int val = data[size];
if ( ( size > 0 ) && ( val < min ) ) {
int prevMin = min;
min += min - val;
return prevMin;
} else {
return val;
}
}
public boolean isEmpty () {
return size == 0;
}
public static void main (String...args) {
StackWithMin stack = new StackWithMin();
for ( String arg: args )
stack.push( Integer.parseInt( arg ) );
while ( ! stack.isEmpty() ) {
int min = stack.getMin();
int val = stack.pop();
System.out.println( val + " " + min );
}
System.out.println();
}
}
It stores the current minimum explicitly, and if the minimum changes, instead of pushing the value, it pushes a value the same difference the other side of the new minimum ( if min = 7 and you push 5, it pushes 3 instead ( 5-|7-5| = 3) and sets min to 5; if you then pop 3 when min is 5 it sees that the popped value is less than min, so reverses the procedure to get 7 for the new min, then returns the previous min). As any value which doesn't cause a change the current minimum is greater than the current minimum, you have something that can be used to differentiate between values which change the minimum and ones which don't.
In languages which use fixed size integers, you're borrowing a bit of space from the representation of the values, so it may underflow and the assert will fail. But otherwise, it's constant extra space and all operations are still O(1).
Stacks which are based instead on linked lists have other places you can borrow a bit from, for example in C the least significant bit of the next pointer, or in Java the type of the objects in the linked list. For Java this does mean there's more space used compared to a contiguous stack, as you have the object overhead per link:
public class LinkedStackWithMin {
private static class Link {
final int value;
final Link next;
Link ( int value, Link next ) {
this.value = value;
this.next = next;
}
int pop ( LinkedStackWithMin stack ) {
stack.top = next;
return value;
}
}
private static class MinLink extends Link {
MinLink ( int value, Link next ) {
super( value, next );
}
int pop ( LinkedStackWithMin stack ) {
stack.top = next;
int prevMin = stack.min;
stack.min = value;
return prevMin;
}
}
Link top;
int min;
public LinkedStackWithMin () {
}
public void push ( int val ) {
if ( ( top == null ) || ( val < min ) ) {
top = new MinLink(min, top);
min = val;
} else {
top = new Link(val, top);
}
}
public int pop () {
return top.pop(this);
}
public int getMin () {
return min;
}
public boolean isEmpty () {
return top == null;
}
In C, the overhead isn't there, and you can borrow the lsb of the next pointer:
typedef struct _stack_link stack_with_min;
typedef struct _stack_link stack_link;
struct _stack_link {
size_t next;
int value;
};
stack_link* get_next ( stack_link* link )
{
return ( stack_link * )( link -> next & ~ ( size_t ) 1 );
}
bool is_min ( stack_link* link )
{
return ( link -> next & 1 ) ! = 0;
}
void push ( stack_with_min* stack, int value )
{
stack_link *link = malloc ( sizeof( stack_link ) );
link -> next = ( size_t ) stack -> next;
if ( (stack -> next == 0) || ( value == stack -> value ) ) {
link -> value = stack -> value;
link -> next |= 1; // mark as min
} else {
link -> value = value;
}
stack -> next = link;
}
etc.;
However, none of these are truly O(1). They don't require any more space in practice, because they exploit holes in the representations of numbers, objects or pointers in these languages. But a theoretical machine which used a more compact representation would require an extra bit to be added to that representation in each case.
I found a solution that satisfies all the constraints mentioned (constant time operations) and constant extra space.
The idea is to store the difference between min value and the input number, and update the min value if it is no longer the minimum.
The code is as follows:
public class MinStack {
long min;
Stack<Long> stack;
public MinStack(){
stack = new Stack<>();
}
public void push(int x) {
if (stack.isEmpty()) {
stack.push(0L);
min = x;
} else {
stack.push(x - min); //Could be negative if min value needs to change
if (x < min) min = x;
}
}
public int pop() {
if (stack.isEmpty()) return;
long pop = stack.pop();
if (pop < 0) {
long ret = min
min = min - pop; //If negative, increase the min value
return (int)ret;
}
return (int)(pop + min);
}
public int top() {
long top = stack.peek();
if (top < 0) {
return (int)min;
} else {
return (int)(top + min);
}
}
public int getMin() {
return (int)min;
}
}
Credit goes to: https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack
Well, what are the runtime constraints of push and pop? If they are not required to be constant, then just calculate the minimum value in those two operations (making them O(n)). Otherwise, I don't see how this can be done with constant additional space.
Let's assume the stack which we will be working on is this :
6 , minvalue=2
2 , minvalue=2
5 , minvalue=3
3 , minvalue=3
9 , minvalue=7
7 , minvalue=7
8 , minvalue=8
In the above representation the stack is only built by left value's the right value's [minvalue] is written only for illustration purpose which will be stored in one variable.
The actual problem is when the value which is the minimum value gets removed: At that point how can we know what is the next minimum element without iterating over the stack.
Like for example in our stack when 6 gets popped we know that, this is not the minimum element because the minimum element is 2, so we can safely remove this without updating our min value.
But when we pop 2, we can see that the minimum value is 2 right now and if this gets popped out then we need to update the minimum value to 3.
Point1:
Now if you observe carefully we need to generate minvalue=3 from this particular state [2 , minvalue=2].
Or if you go deeper in the stack we need to generate minvalue=7 from this particular state [3 , minvalue=3]
or if you go deeper still in the stack then we need to generate minvalue=8 from this particular state [7 , minvalue=7]
Did you notice something in common in all of the above three cases? The value which we need to generate depends upon two variable which are both equal. Correct.
Why is this happening because when we push some element smaller then the current minvalue, then we basically push that element in the stack and updated the same number in minvalue also.
Point2:
So we are basically storing duplicate of the same number once in stack and once in minvalue variable.
We need to focus on avoiding this duplication and store something useful data in the stack or the minvalue to generate the previous minimum as shown in CASES above.
Let's focus on what should we store in stack when the value to store in push is less than the minimum value.
Let's name this variable y, so now our stack will look something like this:
6 , minvalue=2
y1 , minvalue=2
5 , minvalue=3
y2 , minvalue=3
9 , minvalue=7
y3 , minvalue=7
8 , minvalue=8
I have renamed them as y1,y2,y3 to avoid confusion that all of them will have same value.
Point3:
Now let's try to find some constraint's over y1, y2 and y3.
Do you remember when exactly we need to update the minvalue while doing pop(), only when we have popped the element which is equal to the minvalue.
If we pop something greater than the minvalue then we don't have to update minvalue.
So to trigger the update of minvalue, y1,y2&y3 should be smaller than there corresponding minvalue. [We are avoiding equality to avoid duplicate[Point2]]
so the constrain is [ y < minValue ].
Now let's come back to populate y, we need to generate some value and put y at the time of push, remember.
Let's take the value which is coming for push to be x which is less that the prevMinvalue, and the value which we will actually push in stack to be y.
So one thing is obvious that the newMinValue=x, and y < newMinvalue.
Now we need to calculate y(remember y can be any number which is less than newMinValue(x) so we need to find some number which can fulfil our constraint) with the help of prevMinvalue and x(newMinvalue).
Let's do the math:
x < prevMinvalue [Given]
x - prevMinvalue < 0
x - prevMinValue + x < 0 + x [Add x on both side]
2*x - prevMinValue < x
this is the y which we were looking for less than x(newMinValue).
y = 2*x - prevMinValue. 'or' y = 2*newMinValue - prevMinValue 'or' y = 2*curMinValue - prevMinValue [taking curMinValue=newMinValue].
So at the time of pushing x if it is less than prevMinvalue then we push y[2*x-prevMinValue] and update newMinValue = x .
And at the time of pop if the stack contains something less than the minValue then that's our trigger to update the minValue.
We have to calculate prevMinValue from the curMinValue and y.
  y = 2*curMinValue - prevMinValue [Proved]
  prevMinValue = 2*curMinvalue - y .
2*curMinValue - y is the number which we need to update now to the prevMinValue.
Code for the same logic is shared below with O(1) time and O(1) space complexity.
// C++ program to implement a stack that supports
// getMinimum() in O(1) time and O(1) extra space.
#include <bits/stdc++.h>
using namespace std;
// A user defined stack that supports getMin() in
// addition to push() and pop()
struct MyStack
{
stack<int> s;
int minEle;
// Prints minimum element of MyStack
void getMin()
{
if (s.empty())
cout << "Stack is empty\n";
// variable minEle stores the minimum element
// in the stack.
else
cout <<"Minimum Element in the stack is: "
<< minEle << "\n";
}
// Prints top element of MyStack
void peek()
{
if (s.empty())
{
cout << "Stack is empty ";
return;
}
int t = s.top(); // Top element.
cout << "Top Most Element is: ";
// If t < minEle means minEle stores
// value of t.
(t < minEle)? cout << minEle: cout << t;
}
// Remove the top element from MyStack
void pop()
{
if (s.empty())
{
cout << "Stack is empty\n";
return;
}
cout << "Top Most Element Removed: ";
int t = s.top();
s.pop();
// Minimum will change as the minimum element
// of the stack is being removed.
if (t < minEle)
{
cout << minEle << "\n";
minEle = 2*minEle - t;
}
else
cout << t << "\n";
}
// Removes top element from MyStack
void push(int x)
{
// Insert new number into the stack
if (s.empty())
{
minEle = x;
s.push(x);
cout << "Number Inserted: " << x << "\n";
return;
}
// If new number is less than minEle
if (x < minEle)
{
s.push(2*x - minEle);
minEle = x;
}
else
s.push(x);
cout << "Number Inserted: " << x << "\n";
}
};
// Driver Code
int main()
{
MyStack s;
s.push(3);
s.push(5);
s.getMin();
s.push(2);
s.push(1);
s.getMin();
s.pop();
s.getMin();
s.pop();
s.peek();
return 0;
}
We can do this in O(n) time and O(1) space complexity, like so:
class MinStackOptimized:
def __init__(self):
self.stack = []
self.min = None
def push(self, x):
if not self.stack:
# stack is empty therefore directly add
self.stack.append(x)
self.min = x
else:
"""
Directly add (x-self.min) to the stack. This also ensures anytime we have a
negative number on the stack is when x was less than existing minimum
recorded thus far.
"""
self.stack.append(x-self.min)
if x < self.min:
# Update x to new min
self.min = x
def pop(self):
x = self.stack.pop()
if x < 0:
"""
if popped element was negative therefore this was the minimum
element, whose actual value is in self.min but stored value is what
contributes to get the next min. (this is one of the trick we use to ensure
we are able to get old minimum once current minimum gets popped proof is given
below in pop method), value stored during push was:
(x - self.old_min) and self.min = x therefore we need to backtrack
these steps self.min(current) - stack_value(x) actually implies to
x (self.min) - (x - self.old_min)
which therefore gives old_min back and therefore can now be set
back as current self.min.
"""
self.min = self.min - x
def top(self):
x = self.stack[-1]
if x < 0:
"""
As discussed above anytime there is a negative value on stack, this
is the min value so far and therefore actual value is in self.min,
current stack value is just for getting the next min at the time
this gets popped.
"""
return self.min
else:
"""
if top element of the stack was positive then it's simple, it was
not the minimum at the time of pushing it and therefore what we did
was x(actual) - self.min(min element at current stage) let's say `y`
therefore we just need to reverse the process to get the actual
value. Therefore self.min + y, which would translate to
self.min + x(actual) - self.min, thereby giving x(actual) back
as desired.
"""
return x + self.min
def getMin(self):
# Always self.min variable holds the minimum so for so easy peezy.
return self.min
Here is my version of implementation.
struct MyStack {
int element;
int *CurrentMiniAddress;
};
void Push(int value)
{
// Create you structure and populate the value
MyStack S = new MyStack();
S->element = value;
if(Stack.Empty())
{
// Since the stack is empty, point CurrentMiniAddress to itself
S->CurrentMiniAddress = S;
}
else
{
// Stack is not empty
// Retrieve the top element. No Pop()
MyStack *TopElement = Stack.Top();
// Remember Always the TOP element points to the
// minimum element in ths whole stack
if (S->element CurrentMiniAddress->element)
{
// If the current value is the minimum in the whole stack
// then S points to itself
S->CurrentMiniAddress = S;
}
else
{
// So this is not the minimum in the whole stack
// No worries, TOP is holding the minimum element
S->CurrentMiniAddress = TopElement->CurrentMiniAddress;
}
}
Stack.Add(S);
}
void Pop()
{
if(!Stack.Empty())
{
Stack.Pop();
}
}
int GetMinimum(Stack &stack)
{
if(!stack.Empty())
{
MyStack *Top = stack.top();
// Top always points to the minimumx
return Top->CurrentMiniAddress->element;
}
}
Here is my Code which runs with O(1). The previous code which I posted had problem when the minimum element gets popped. I modified my code. This one uses another Stack that maintains minimum element present in stack above the current pushed element.
class StackDemo
{
int[] stk = new int[100];
int top;
public StackDemo()
{
top = -1;
}
public void Push(int value)
{
if (top == 100)
Console.WriteLine("Stack Overflow");
else
stk[++top] = value;
}
public bool IsEmpty()
{
if (top == -1)
return true;
else
return false;
}
public int Pop()
{
if (IsEmpty())
{
Console.WriteLine("Stack Underflow");
return 0;
}
else
return stk[top--];
}
public void Display()
{
for (int i = top; i >= 0; i--)
Console.WriteLine(stk[i]);
}
}
class MinStack : StackDemo
{
int top;
int[] stack = new int[100];
StackDemo s1; int min;
public MinStack()
{
top = -1;
s1 = new StackDemo();
}
public void PushElement(int value)
{
s1.Push(value);
if (top == 100)
Console.WriteLine("Stack Overflow");
if (top == -1)
{
stack[++top] = value;
stack[++top] = value;
}
else
{
// stack[++top]=value;
int ele = PopElement();
stack[++top] = ele;
int a = MininmumElement(min, value);
stack[++top] = min;
stack[++top] = value;
stack[++top] = a;
}
}
public int PopElement()
{
if (top == -1)
return 1000;
else
{
min = stack[top--];
return stack[top--];
}
}
public int PopfromStack()
{
if (top == -1)
return 1000;
else
{
s1.Pop();
return PopElement();
}
}
public int MininmumElement(int a,int b)
{
if (a > b)
return b;
else
return a;
}
public int StackTop()
{
return stack[top];
}
public void DisplayMinStack()
{
for (int i = top; i >= 0; i--)
Console.WriteLine(stack[i]);
}
}
class Program
{
static void Main(string[] args)
{
MinStack ms = new MinStack();
ms.PushElement(15);
ms.PushElement(2);
ms.PushElement(1);
ms.PushElement(13);
ms.PushElement(5);
ms.PushElement(21);
Console.WriteLine("Min Stack");
ms.DisplayMinStack();
Console.WriteLine("Minimum Element:"+ms.StackTop());
ms.PopfromStack();
ms.PopfromStack();
ms.PopfromStack();
ms.PopfromStack();
Console.WriteLine("Min Stack");
ms.DisplayMinStack();
Console.WriteLine("Minimum Element:" + ms.StackTop());
Thread.Sleep(1000000);
}
}
I used a different kind of stack. Here is the implementation.
//
// main.cpp
// Eighth
//
// Created by chaitanya on 4/11/13.
// Copyright (c) 2013 cbilgika. All rights reserved.
//
#include <iostream>
#include <limits>
using namespace std;
struct stack
{
int num;
int minnum;
}a[100];
void push(int n,int m,int &top)
{
top++;
if (top>=100) {
cout<<"Stack Full";
cout<<endl;
}
else{
a[top].num = n;
a[top].minnum = m;
}
}
void pop(int &top)
{
if (top<0) {
cout<<"Stack Empty";
cout<<endl;
}
else{
top--;
}
}
void print(int &top)
{
cout<<"Stack: "<<endl;
for (int j = 0; j<=top ; j++) {
cout<<"("<<a[j].num<<","<<a[j].minnum<<")"<<endl;
}
}
void get_min(int &top)
{
if (top < 0)
{
cout<<"Empty Stack";
}
else{
cout<<"Minimum element is: "<<a[top].minnum;
}
cout<<endl;
}
int main()
{
int top = -1,min = numeric_limits<int>::min(),num;
cout<<"Enter the list to push (-1 to stop): ";
cin>>num;
while (num!=-1) {
if (top == -1) {
min = num;
push(num, min, top);
}
else{
if (num < min) {
min = num;
}
push(num, min, top);
}
cin>>num;
}
print(top);
get_min(top);
return 0;
}
Output:
Enter the list to push (-1 to stop): 5
1
4
6
2
-1
Stack:
(5,5)
(1,1)
(4,1)
(6,1)
(2,1)
Minimum element is: 1
Try it. I think it answers the question. The second element of every pair gives the minimum value seen when that element was inserted.
I am posting the complete code here to find min and max in a given stack.
Time complexity will be O(1)..
package com.java.util.collection.advance.datastructure;
/**
*
* #author vsinha
*
*/
public abstract interface Stack<E> {
/**
* Placing a data item on the top of the stack is called pushing it
* #param element
*
*/
public abstract void push(E element);
/**
* Removing it from the top of the stack is called popping it
* #return the top element
*/
public abstract E pop();
/**
* Get it top element from the stack and it
* but the item is not removed from the stack, which remains unchanged
* #return the top element
*/
public abstract E peek();
/**
* Get the current size of the stack.
* #return
*/
public abstract int size();
/**
* Check whether stack is empty of not.
* #return true if stack is empty, false if stack is not empty
*/
public abstract boolean empty();
}
package com.java.util.collection.advance.datastructure;
#SuppressWarnings("hiding")
public abstract interface MinMaxStack<Integer> extends Stack<Integer> {
public abstract int min();
public abstract int max();
}
package com.java.util.collection.advance.datastructure;
import java.util.Arrays;
/**
*
* #author vsinha
*
* #param <E>
*/
public class MyStack<E> implements Stack<E> {
private E[] elements =null;
private int size = 0;
private int top = -1;
private final static int DEFAULT_INTIAL_CAPACITY = 10;
public MyStack(){
// If you don't specify the size of stack. By default, Stack size will be 10
this(DEFAULT_INTIAL_CAPACITY);
}
#SuppressWarnings("unchecked")
public MyStack(int intialCapacity){
if(intialCapacity <=0){
throw new IllegalArgumentException("initial capacity can't be negative or zero");
}
// Can't create generic type array
elements =(E[]) new Object[intialCapacity];
}
#Override
public void push(E element) {
ensureCapacity();
elements[++top] = element;
++size;
}
#Override
public E pop() {
E element = null;
if(!empty()) {
element=elements[top];
// Nullify the reference
elements[top] =null;
--top;
--size;
}
return element;
}
#Override
public E peek() {
E element = null;
if(!empty()) {
element=elements[top];
}
return element;
}
#Override
public int size() {
return size;
}
#Override
public boolean empty() {
return size == 0;
}
/**
* Increases the capacity of this <tt>Stack by double of its current length</tt> instance,
* if stack is full
*/
private void ensureCapacity() {
if(size != elements.length) {
// Don't do anything. Stack has space.
} else{
elements = Arrays.copyOf(elements, size *2);
}
}
#Override
public String toString() {
return "MyStack [elements=" + Arrays.toString(elements) + ", size="
+ size + ", top=" + top + "]";
}
}
package com.java.util.collection.advance.datastructure;
/**
* Time complexity will be O(1) to find min and max in a given stack.
* #author vsinha
*
*/
public class MinMaxStackFinder extends MyStack<Integer> implements MinMaxStack<Integer> {
private MyStack<Integer> minStack;
private MyStack<Integer> maxStack;
public MinMaxStackFinder (int intialCapacity){
super(intialCapacity);
minStack =new MyStack<Integer>();
maxStack =new MyStack<Integer>();
}
public void push(Integer element) {
// Current element is lesser or equal than min() value, Push the current element in min stack also.
if(!minStack.empty()) {
if(min() >= element) {
minStack.push(element);
}
} else{
minStack.push(element);
}
// Current element is greater or equal than max() value, Push the current element in max stack also.
if(!maxStack.empty()) {
if(max() <= element) {
maxStack.push(element);
}
} else{
maxStack.push(element);
}
super.push(element);
}
public Integer pop(){
Integer curr = super.pop();
if(curr !=null) {
if(min() == curr) {
minStack.pop();
}
if(max() == curr){
maxStack.pop();
}
}
return curr;
}
#Override
public int min() {
return minStack.peek();
}
#Override
public int max() {
return maxStack.peek();
}
#Override
public String toString() {
return super.toString()+"\nMinMaxStackFinder [minStack=" + minStack + "\n maxStack="
+ maxStack + "]" ;
}
}
// You can use the below program to execute it.
package com.java.util.collection.advance.datastructure;
import java.util.Random;
public class MinMaxStackFinderApp {
public static void main(String[] args) {
MinMaxStack<Integer> stack =new MinMaxStackFinder(10);
Random random =new Random();
for(int i =0; i< 10; i++){
stack.push(random.nextInt(100));
}
System.out.println(stack);
System.out.println("MAX :"+stack.max());
System.out.println("MIN :"+stack.min());
stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();
System.out.println(stack);
System.out.println("MAX :"+stack.max());
System.out.println("MIN :"+stack.min());
}
}
Let me know if you are facing any issue
Thanks,
Vikash
class FastStack {
private static class StackNode {
private Integer data;
private StackNode nextMin;
public StackNode(Integer data) {
this.data = data;
}
public Integer getData() {
return data;
}
public void setData(Integer data) {
this.data = data;
}
public StackNode getNextMin() {
return nextMin;
}
public void setNextMin(StackNode nextMin) {
this.nextMin = nextMin;
}
}
private LinkedList<StackNode> stack = new LinkedList<>();
private StackNode currentMin = null;
public void push(Integer item) {
StackNode node = new StackNode(item);
if (currentMin == null) {
currentMin = node;
node.setNextMin(null);
} else if (item < currentMin.getData()) {
StackNode oldMinNode = currentMin;
node.setNextMin(oldMinNode);
currentMin = node;
}
stack.addFirst(node);
}
public Integer pop() {
if (stack.isEmpty()) {
throw new EmptyStackException();
}
StackNode node = stack.peek();
if (currentMin == node) {
currentMin = node.getNextMin();
}
stack.removeFirst();
return node.getData();
}
public Integer getMinimum() {
if (stack.isEmpty()) {
throw new NoSuchElementException("Stack is empty");
}
return currentMin.getData();
}
}
Here is my Code which runs with O(1). Here I used vector pair which contain the value which pushed and also contain the minimum value up to this pushed value.
Here is my version of C++ implementation.
vector<pair<int,int> >A;
int sz=0; // to keep track of the size of vector
class MinStack
{
public:
MinStack()
{
A.clear();
sz=0;
}
void push(int x)
{
int mn=(sz==0)?x: min(A[sz-1].second,x); //find the minimum value upto this pushed value
A.push_back(make_pair(x,mn));
sz++; // increment the size
}
void pop()
{
if(sz==0) return;
A.pop_back(); // pop the last inserted element
sz--; // decrement size
}
int top()
{
if(sz==0) return -1; // if stack empty return -1
return A[sz-1].first; // return the top element
}
int getMin()
{
if(sz==0) return -1;
return A[sz-1].second; // return the minimum value at sz-1
}
};
**The task can be acheived by creating two stacks:**
import java.util.Stack;
/*
*
* Find min in stack using O(n) Space Complexity
*/
public class DeleteMinFromStack {
void createStack(Stack<Integer> primary, Stack<Integer> minStack, int[] arr) {
/* Create main Stack and in parallel create the stack which contains the minimum seen so far while creating main Stack */
primary.push(arr[0]);
minStack.push(arr[0]);
for (int i = 1; i < arr.length; i++) {
primary.push(arr[i]);
if (arr[i] <= minStack.peek())// Condition to check to push the value in minimum stack only when this urrent value is less than value seen at top of this stack */
minStack.push(arr[i]);
}
}
int findMin(Stack<Integer> secStack) {
return secStack.peek();
}
public static void main(String args[]) {
Stack<Integer> primaryStack = new Stack<Integer>();
Stack<Integer> minStack = new Stack<Integer>();
DeleteMinFromStack deleteMinFromStack = new DeleteMinFromStack();
int[] arr = { 5, 5, 6, 8, 13, 1, 11, 6, 12 };
deleteMinFromStack.createStack(primaryStack, minStack, arr);
int mimElement = deleteMinFromStack.findMin(primaryStack, minStack);
/** This check for algorithm when the main Stack Shrinks by size say i as in loop below */
for (int i = 0; i < 2; i++) {
primaryStack.pop();
}
System.out.println(" Minimum element is " + mimElement);
}
}
/*
here in have tried to add for loop wherin the main tack can be shrinked/expaned so we can check the algorithm */
A practical implementation for finding minimum in a Stack of User Designed Object,
named: School
The Stack is going to store the Schools in Stack based on the rank assigned to a school in specific region, say, findMin() gives the School where we get the maximum number of applications for Admissions, which in turn is to be defined by the comparator which uses rank associated with the schools in previous season .
The Code for same is below:
package com.practical;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class CognitaStack {
public School findMin(Stack<School> stack, Stack<School> minStack) {
if (!stack.empty() && !minStack.isEmpty())
return (School) minStack.peek();
return null;
}
public School removeSchool(Stack<School> stack, Stack<School> minStack) {
if (stack.isEmpty())
return null;
School temp = stack.peek();
if (temp != null) {
// if(temp.compare(stack.peek(), minStack.peek())<0){
stack.pop();
minStack.pop();
// }
// stack.pop();
}
return stack.peek();
}
public static void main(String args[]) {
Stack<School> stack = new Stack<School>();
Stack<School> minStack = new Stack<School>();
List<School> lst = new LinkedList<School>();
School s1 = new School("Polam School", "London", 3);
School s2 = new School("AKELEY WOOD SENIOR SCHOOL", "BUCKINGHAM", 4);
School s3 = new School("QUINTON HOUSE SCHOOL", "NORTHAMPTON", 2);
School s4 = new School("OAKLEIGH HOUSE SCHOOL", " SWANSEA", 5);
School s5 = new School("OAKLEIGH-OAK HIGH SCHOOL", "Devon", 1);
School s6 = new School("BritishInter2", "Devon", 7);
lst.add(s1);
lst.add(s2);
lst.add(s3);
lst.add(s4);
lst.add(s5);
lst.add(s6);
Iterator<School> itr = lst.iterator();
while (itr.hasNext()) {
School temp = itr.next();
if ((minStack.isEmpty()) || (temp.compare(temp, minStack.peek()) < 0)) { // minStack.peek().equals(temp)
stack.push(temp);
minStack.push(temp);
} else {
minStack.push(minStack.peek());
stack.push(temp);
}
}
CognitaStack cogStack = new CognitaStack();
System.out.println(" Minimum in Stack is " + cogStack.findMin(stack, minStack).name);
cogStack.removeSchool(stack, minStack);
cogStack.removeSchool(stack, minStack);
System.out.println(" Minimum in Stack is "
+ ((cogStack.findMin(stack, minStack) != null) ? cogStack.findMin(stack, minStack).name : "Empty"));
}
}
Also the School Object is as follows:
package com.practical;
import java.util.Comparator;
public class School implements Comparator<School> {
String name;
String location;
int rank;
public School(String name, String location, int rank) {
super();
this.name = name;
this.location = location;
this.rank = rank;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + rank;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
School other = (School) obj;
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (rank != other.rank)
return false;
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public int compare(School o1, School o2) {
// TODO Auto-generated method stub
return o1.rank - o2.rank;
}
}
class SchoolComparator implements Comparator<School> {
public int compare(School o1, School o2) {
return o1.rank - o2.rank;
}
}
This Example covers the following:
1. Implementation of Stack for User defined Objects, here, School
2. Implementation for the hashcode() and equals() method using all fields of Objects to be compared
3. A practical implementation for the scenario where we rqeuire to get the Stack contains operation to be in order of O(1)
Here's the PHP implementation of what explained in Jon Skeet's answer as the slightly better space complexity implementation to get the maximum of stack in O(1).
<?php
/**
* An ordinary stack implementation.
*
* In real life we could just extend the built-in "SplStack" class.
*/
class BaseIntegerStack
{
/**
* Stack main storage.
*
* #var array
*/
private $storage = [];
// ------------------------------------------------------------------------
// Public API
// ------------------------------------------------------------------------
/**
* Pushes to stack.
*
* #param int $value New item.
*
* #return bool
*/
public function push($value)
{
return is_integer($value)
? (bool) array_push($this->storage, $value)
: false;
}
/**
* Pops an element off the stack.
*
* #return int
*/
public function pop()
{
return array_pop($this->storage);
}
/**
* See what's on top of the stack.
*
* #return int|bool
*/
public function top()
{
return empty($this->storage)
? false
: end($this->storage);
}
// ------------------------------------------------------------------------
// Magic methods
// ------------------------------------------------------------------------
/**
* String representation of the stack.
*
* #return string
*/
public function __toString()
{
return implode('|', $this->storage);
}
} // End of BaseIntegerStack class
/**
* The stack implementation with getMax() method in O(1).
*/
class Stack extends BaseIntegerStack
{
/**
* Internal stack to keep track of main stack max values.
*
* #var BaseIntegerStack
*/
private $maxStack;
/**
* Stack class constructor.
*
* Dependencies are injected.
*
* #param BaseIntegerStack $stack Internal stack.
*
* #return void
*/
public function __construct(BaseIntegerStack $stack)
{
$this->maxStack = $stack;
}
// ------------------------------------------------------------------------
// Public API
// ------------------------------------------------------------------------
/**
* Prepends an item into the stack maintaining max values.
*
* #param int $value New item to push to the stack.
*
* #return bool
*/
public function push($value)
{
if ($this->isNewMax($value)) {
$this->maxStack->push($value);
}
parent::push($value);
}
/**
* Pops an element off the stack maintaining max values.
*
* #return int
*/
public function pop()
{
$popped = parent::pop();
if ($popped == $this->maxStack->top()) {
$this->maxStack->pop();
}
return $popped;
}
/**
* Finds the maximum of stack in O(1).
*
* #return int
* #see push()
*/
public function getMax()
{
return $this->maxStack->top();
}
// ------------------------------------------------------------------------
// Internal helpers
// ------------------------------------------------------------------------
/**
* Checks that passing value is a new stack max or not.
*
* #param int $new New integer to check.
*
* #return boolean
*/
private function isNewMax($new)
{
return empty($this->maxStack) OR $new > $this->maxStack->top();
}
} // End of Stack class
// ------------------------------------------------------------------------
// Stack Consumption and Test
// ------------------------------------------------------------------------
$stack = new Stack(
new BaseIntegerStack
);
$stack->push(9);
$stack->push(4);
$stack->push(237);
$stack->push(5);
$stack->push(556);
$stack->push(15);
print "Stack: $stack\n";
print "Max: {$stack->getMax()}\n\n";
print "Pop: {$stack->pop()}\n";
print "Pop: {$stack->pop()}\n\n";
print "Stack: $stack\n";
print "Max: {$stack->getMax()}\n\n";
print "Pop: {$stack->pop()}\n";
print "Pop: {$stack->pop()}\n\n";
print "Stack: $stack\n";
print "Max: {$stack->getMax()}\n";
// Here's the sample output:
//
// Stack: 9|4|237|5|556|15
// Max: 556
//
// Pop: 15
// Pop: 556
//
// Stack: 9|4|237|5
// Max: 237
//
// Pop: 5
// Pop: 237
//
// Stack: 9|4
// Max: 9
Here is the C++ implementation of Jon Skeets Answer.
It might not be the most optimal way of implementing it, but it does exactly what it's supposed to.
class Stack {
private:
struct stack_node {
int val;
stack_node *next;
};
stack_node *top;
stack_node *min_top;
public:
Stack() {
top = nullptr;
min_top = nullptr;
}
void push(int num) {
stack_node *new_node = nullptr;
new_node = new stack_node;
new_node->val = num;
if (is_empty()) {
top = new_node;
new_node->next = nullptr;
min_top = new_node;
new_node->next = nullptr;
} else {
new_node->next = top;
top = new_node;
if (new_node->val <= min_top->val) {
new_node->next = min_top;
min_top = new_node;
}
}
}
void pop(int &num) {
stack_node *tmp_node = nullptr;
stack_node *min_tmp = nullptr;
if (is_empty()) {
std::cout << "It's empty\n";
} else {
num = top->val;
if (top->val == min_top->val) {
min_tmp = min_top->next;
delete min_top;
min_top = min_tmp;
}
tmp_node = top->next;
delete top;
top = tmp_node;
}
}
bool is_empty() const {
return !top;
}
void get_min(int &item) {
item = min_top->val;
}
};
And here is the driver for the class
int main() {
int pop, min_el;
Stack my_stack;
my_stack.push(4);
my_stack.push(6);
my_stack.push(88);
my_stack.push(1);
my_stack.push(234);
my_stack.push(2);
my_stack.get_min(min_el);
cout << "Min: " << min_el << endl;
my_stack.pop(pop);
cout << "Popped stock element: " << pop << endl;
my_stack.pop(pop);
cout << "Popped stock element: " << pop << endl;
my_stack.pop(pop);
cout << "Popped stock element: " << pop << endl;
my_stack.get_min(min_el);
cout << "Min: " << min_el << endl;
return 0;
}
Output:
Min: 1
Popped stock element: 2
Popped stock element: 234
Popped stock element: 1
Min: 4
You could extend your original stack class and just add the min tracking to it. Let the original parent class handle everything else as usual.
public class StackWithMin extends Stack<Integer> {
private Stack<Integer> min;
public StackWithMin() {
min = new Stack<>();
}
public void push(int num) {
if (super.isEmpty()) {
min.push(num);
} else if (num <= min.peek()) {
min.push(num);
}
super.push(num);
}
public int min() {
return min.peek();
}
public Integer pop() {
if (super.peek() == min.peek()) {
min.pop();
}
return super.pop();
}
}
I think you can simply use a LinkedList in your stack implementation.
First time you push a value, you put this value as the linkedlist head.
then each time you push a value, if the new value < head.data, make a prepand operation ( which means the head becomes the new value )
if not, then make an append operation.
When you make a pop(), you check if min == linkedlist.head.data, if yes, then head=head.next;
Here is my code.
public class Stack {
int[] elements;
int top;
Linkedlists min;
public Stack(int n) {
elements = new int[n];
top = 0;
min = new Linkedlists();
}
public void realloc(int n) {
int[] tab = new int[n];
for (int i = 0; i < top; i++) {
tab[i] = elements[i];
}
elements = tab;
}
public void push(int x) {
if (top == elements.length) {
realloc(elements.length * 2);
}
if (top == 0) {
min.pre(x);
} else if (x < min.head.data) {
min.pre(x);
} else {
min.app(x);
}
elements[top++] = x;
}
public int pop() {
int x = elements[--top];
if (top == 0) {
}
if (this.getMin() == x) {
min.head = min.head.next;
}
elements[top] = 0;
if (4 * top < elements.length) {
realloc((elements.length + 1) / 2);
}
return x;
}
public void display() {
for (Object x : elements) {
System.out.print(x + " ");
}
}
public int getMin() {
if (top == 0) {
return 0;
}
return this.min.head.data;
}
public static void main(String[] args) {
Stack stack = new Stack(4);
stack.push(2);
stack.push(3);
stack.push(1);
stack.push(4);
stack.push(5);
stack.pop();
stack.pop();
stack.pop();
stack.push(1);
stack.pop();
stack.pop();
stack.pop();
stack.push(2);
System.out.println(stack.getMin());
stack.display();
}
}
Here is my solution in java using liked list.
class Stack{
int min;
Node top;
static class Node{
private int data;
private Node next;
private int min;
Node(int data, int min){
this.data = data;
this.min = min;
this.next = null;
}
}
void push(int data){
Node temp;
if(top == null){
temp = new Node(data,data);
top = temp;
top.min = data;
}
if(top.min > data){
temp = new Node(data,data);
temp.next = top;
top = temp;
} else {
temp = new Node(data, top.min);
temp.next = top;
top = temp;
}
}
void pop(){
if(top != null){
top = top.next;
}
}
int min(){
return top.min;
}
}
public class MinStack<E>{
private final LinkedList<E> mainStack = new LinkedList<E>();
private final LinkedList<E> minStack = new LinkedList<E>();
private final Comparator<E> comparator;
public MinStack(Comparator<E> comparator)
{
this.comparator = comparator;
}
/**
* Pushes an element onto the stack.
*
*
* #param e the element to push
*/
public void push(E e) {
mainStack.push(e);
if(minStack.isEmpty())
{
minStack.push(e);
}
else if(comparator.compare(e, minStack.peek())<=0)
{
minStack.push(e);
}
else
{
minStack.push(minStack.peek());
}
}
/**
* Pops an element from the stack.
*
*
* #throws NoSuchElementException if this stack is empty
*/
public E pop() {
minStack.pop();
return mainStack.pop();
}
/**
* Returns but not remove smallest element from the stack. Return null if stack is empty.
*
*/
public E getMinimum()
{
return minStack.peek();
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Main stack{");
for (E e : mainStack) {
sb.append(e.toString()).append(",");
}
sb.append("}");
sb.append(" Min stack{");
for (E e : minStack) {
sb.append(e.toString()).append(",");
}
sb.append("}");
sb.append(" Minimum = ").append(getMinimum());
return sb.toString();
}
public static void main(String[] args) {
MinStack<Integer> st = new MinStack<Integer>(Comparators.INTEGERS);
st.push(2);
Assert.assertTrue("2 is min in stack {2}", st.getMinimum().equals(2));
System.out.println(st);
st.push(6);
Assert.assertTrue("2 is min in stack {2,6}", st.getMinimum().equals(2));
System.out.println(st);
st.push(4);
Assert.assertTrue("2 is min in stack {2,6,4}", st.getMinimum().equals(2));
System.out.println(st);
st.push(1);
Assert.assertTrue("1 is min in stack {2,6,4,1}", st.getMinimum().equals(1));
System.out.println(st);
st.push(5);
Assert.assertTrue("1 is min in stack {2,6,4,1,5}", st.getMinimum().equals(1));
System.out.println(st);
st.pop();
Assert.assertTrue("1 is min in stack {2,6,4,1}", st.getMinimum().equals(1));
System.out.println(st);
st.pop();
Assert.assertTrue("2 is min in stack {2,6,4}", st.getMinimum().equals(2));
System.out.println(st);
st.pop();
Assert.assertTrue("2 is min in stack {2,6}", st.getMinimum().equals(2));
System.out.println(st);
st.pop();
Assert.assertTrue("2 is min in stack {2}", st.getMinimum().equals(2));
System.out.println(st);
st.pop();
Assert.assertTrue("null is min in stack {}", st.getMinimum()==null);
System.out.println(st);
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Solution
{
public class MinStack
{
public MinStack()
{
MainStack=new Stack<int>();
Min=new Stack<int>();
}
static Stack<int> MainStack;
static Stack<int> Min;
public void Push(int item)
{
MainStack.Push(item);
if(Min.Count==0 || item<Min.Peek())
Min.Push(item);
}
public void Pop()
{
if(Min.Peek()==MainStack.Peek())
Min.Pop();
MainStack.Pop();
}
public int Peek()
{
return MainStack.Peek();
}
public int GetMin()
{
if(Min.Count==0)
throw new System.InvalidOperationException("Stack Empty");
return Min.Peek();
}
}
}
Saw a brilliant solution here:
https://www.geeksforgeeks.org/design-a-stack-that-supports-getmin-in-o1-time-and-o1-extra-space/
Bellow is the python code I wrote by following the algorithm:
class Node:
def __init__(self, value):
self.value = value
self.next = None
class MinStack:
def __init__(self):
self.head = None
self.min = float('inf')
# #param x, an integer
def push(self, x):
if self.head == None:
self.head = Node(x)
self.min = x
else:
if x >= self.min:
n = Node(x)
n.next = self.head
self.head = n
else:
v = 2 * x - self.min
n = Node(v)
n.next = self.head
self.head = n
self.min = x
# #return nothing
def pop(self):
if self.head:
if self.head.value < self.min:
self.min = self.min * 2 - self.head.value
self.head = self.head.next
# #return an integer
def top(self):
if self.head:
if self.head.value < self.min:
self.min = self.min * 2 - self.head.value
return self.min
else:
return self.head.value
else:
return -1
# #return an integer
def getMin(self):
if self.head:
return self.min
else:
return -1
To getMin elements from Stack. We have to use Two stack .i.e Stack s1 and Stack s2.
Initially, both stacks are empty, so add elements to both stacks
---------------------Recursively call Step 2 to 4-----------------------
if New element added to stack s1.Then pop elements from stack s2
compare new elments with s2. which one is smaller , push to s2.
pop from stack s2(which contains min element)
Code looks like:
package Stack;
import java.util.Stack;
public class getMin
{
Stack<Integer> s1= new Stack<Integer>();
Stack<Integer> s2 = new Stack<Integer>();
void push(int x)
{
if(s1.isEmpty() || s2.isEmpty())
{
s1.push(x);
s2.push(x);
}
else
{
s1. push(x);
int y = (Integer) s2.pop();
s2.push(y);
if(x < y)
s2.push(x);
}
}
public Integer pop()
{
int x;
x=(Integer) s1.pop();
s2.pop();
return x;
}
public int getmin()
{
int x1;
x1= (Integer)s2.pop();
s2.push(x1);
return x1;
}
public static void main(String[] args) {
getMin s = new getMin();
s.push(10);
s.push(20);
s.push(30);
System.out.println(s.getmin());
s.push(1);
System.out.println(s.getmin());
}
}
I have better solution, with O(1) time and with no extra space, You need to push element as String as <original_value,minimum_value>.
For example find this stack of string.
|-1,-1 |
| 1,1 |
| 2,2 |
| 5,3 |
| 3,3 |
Now u can always find min value at current instance by just using peek and checking what is min value at the given instance. this is O(1) time without extra space
class MyStackImplementation{
private final int capacity = 4;
int min;
int arr[] = new int[capacity];
int top = -1;
public void push ( int val ) {
top++;
if(top <= capacity-1){
if(top == 0){
min = val;
arr[top] = val;
}
else if(val < min){
arr[top] = arr[top]+min;
min = arr[top]-min;
arr[top] = arr[top]-min;
}
else {
arr[top] = val;
}
System.out.println("element is pushed");
}
else System.out.println("stack is full");
}
public void pop () {
top--;
if(top > -1){
min = arr[top];
}
else {min=0; System.out.println("stack is under flow");}
}
public int min(){
return min;
}
public boolean isEmpty () {
return top == 0;
}
public static void main(String...s){
MyStackImplementation msi = new MyStackImplementation();
msi.push(1);
msi.push(4);
msi.push(2);
msi.push(10);
System.out.println(msi.min);
msi.pop();
msi.pop();
msi.pop();
msi.pop();
msi.pop();
System.out.println(msi.min);
}
}
I think only push operation suffers, is enough. My implementation includes a stack of nodes. Each node contain the data item and also the minimum on that moment. This minimum is updated each time a push operation is done.
Here are some points for understanding:
I implemented the stack using Linked List.
A pointer top always points to the last pushed item. When there is no item in that stack top is NULL.
When an item is pushed a new node is allocated which has a next pointer that points to the previous stack and top is updated to point to this new node.
Only difference with normal stack implementation is that during push it updates a member min for the new node.
Please have a look at code which is implemented in C++ for demonstration purpose.
/*
* Implementation of Stack that can give minimum in O(1) time all the time
* This solution uses same data structure for minimum variable, it could be implemented using pointers but that will be more space consuming
*/
#include <iostream>
using namespace std;
typedef struct stackLLNodeType stackLLNode;
struct stackLLNodeType {
int item;
int min;
stackLLNode *next;
};
class DynamicStack {
private:
int stackSize;
stackLLNode *top;
public:
DynamicStack();
~DynamicStack();
void push(int x);
int pop();
int getMin();
int size() { return stackSize; }
};
void pushOperation(DynamicStack& p_stackObj, int item);
void popOperation(DynamicStack& p_stackObj);
int main () {
DynamicStack stackObj;
pushOperation(stackObj, 3);
pushOperation(stackObj, 1);
pushOperation(stackObj, 2);
popOperation(stackObj);
popOperation(stackObj);
popOperation(stackObj);
popOperation(stackObj);
pushOperation(stackObj, 4);
pushOperation(stackObj, 7);
pushOperation(stackObj, 6);
popOperation(stackObj);
popOperation(stackObj);
popOperation(stackObj);
popOperation(stackObj);
return 0;
}
DynamicStack::DynamicStack() {
// initialization
stackSize = 0;
top = NULL;
}
DynamicStack::~DynamicStack() {
stackLLNode* tmp;
// chain memory deallocation to avoid memory leak
while (top) {
tmp = top;
top = top->next;
delete tmp;
}
}
void DynamicStack::push(int x) {
// allocate memory for new node assign to top
if (top==NULL) {
top = new stackLLNode;
top->item = x;
top->next = NULL;
top->min = top->item;
}
else {
// allocation of memory
stackLLNode *tmp = new stackLLNode;
// assign the new item
tmp->item = x;
tmp->next = top;
// store the minimum so that it does not get lost after pop operation of later minimum
if (x < top->min)
tmp->min = x;
else
tmp->min = top->min;
// update top to new node
top = tmp;
}
stackSize++;
}
int DynamicStack::pop() {
// check if stack is empty
if (top == NULL)
return -1;
stackLLNode* tmp = top;
int curItem = top->item;
top = top->next;
delete tmp;
stackSize--;
return curItem;
}
int DynamicStack::getMin() {
if (top == NULL)
return -1;
return top->min;
}
void pushOperation(DynamicStack& p_stackObj, int item) {
cout<<"Just pushed: "<<item<<endl;
p_stackObj.push(item);
cout<<"Current stack min: "<<p_stackObj.getMin()<<endl;
cout<<"Current stack size: "<<p_stackObj.size()<<endl<<endl;
}
void popOperation(DynamicStack& p_stackObj) {
int popItem = -1;
if ((popItem = p_stackObj.pop()) == -1 )
cout<<"Cannot pop. Stack is empty."<<endl;
else {
cout<<"Just popped: "<<popItem<<endl;
if (p_stackObj.getMin() == -1)
cout<<"No minimum. Stack is empty."<<endl;
else
cout<<"Current stack min: "<<p_stackObj.getMin()<<endl;
cout<<"Current stack size: "<<p_stackObj.size()<<endl<<endl;
}
}
And the output of the program looks like this:
Just pushed: 3
Current stack min: 3
Current stack size: 1
Just pushed: 1
Current stack min: 1
Current stack size: 2
Just pushed: 2
Current stack min: 1
Current stack size: 3
Just popped: 2
Current stack min: 1
Current stack size: 2
Just popped: 1
Current stack min: 3
Current stack size: 1
Just popped: 3
No minimum. Stack is empty.
Current stack size: 0
Cannot pop. Stack is empty.
Just pushed: 4
Current stack min: 4
Current stack size: 1
Just pushed: 7
Current stack min: 4
Current stack size: 2
Just pushed: 6
Current stack min: 4
Current stack size: 3
Just popped: 6
Current stack min: 4
Current stack size: 2
Just popped: 7
Current stack min: 4
Current stack size: 1
Just popped: 4
No minimum. Stack is empty.
Current stack size: 0
Cannot pop. Stack is empty.
#include<stdio.h>
struct stack
{
int data;
int mindata;
}a[100];
void push(int *tos,int input)
{
if (*tos > 100)
{
printf("overflow");
return;
}
(*tos)++;
a[(*tos)].data=input;
if (0 == *tos)
a[*tos].mindata=input;
else if (a[*tos -1].mindata < input)
a[*tos].mindata=a[*tos -1].mindata;
else
a[*tos].mindata=input;
}
int pop(int * tos)
{
if (*tos <= -1)
{
printf("underflow");
return -1;
}
return(a[(*tos)--].data);
}
void display(int tos)
{
while (tos > -1)
{
printf("%d:%d\t",a[tos].data,a[tos].mindata);
tos--;
}
}
int min(int tos)
{
return(a[tos].mindata);
}
int main()
{
int tos=-1,x,choice;
while(1)
{
printf("press 1-push,2-pop,3-mindata,4-display,5-exit ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("enter data to push");
scanf("%d",&x);
push(&tos,x);
break;
case 2: printf("the poped out data=%d ",pop(&tos));
break;
case 3: printf("The min peeped data:%d",min(tos));
break;
case 4: printf("The elements of stack \n");
display(tos);
break;
default: exit(0);
}
}
I found this solution here
struct StackGetMin {
void push(int x) {
elements.push(x);
if (minStack.empty() || x <= minStack.top())
minStack.push(x);
}
bool pop() {
if (elements.empty()) return false;
if (elements.top() == minStack.top())
minStack.pop();
elements.pop();
return true;
}
bool getMin(int &min) {
if (minStack.empty()) {
return false;
} else {
min = minStack.top();
return true;
}
}
stack<int> elements;
stack<int> minStack;
};
struct Node {
let data: Int
init(_ d:Int){
data = d
}
}
struct Stack {
private var backingStore = [Node]()
private var minArray = [Int]()
mutating func push(n:Node) {
backingStore.append(n)
minArray.append(n.data)
minArray.sort(>)
minArray
}
mutating func pop() -> Node? {
if(backingStore.isEmpty){
return nil
}
let n = backingStore.removeLast()
var found = false
minArray = minArray.filter{
if (!found && $0 == n.data) {
found = true
return false
}
return true
}
return n
}
func min() -> Int? {
return minArray.last
}
}

Resources