How to implement 3 stacks with one array?

后端 未结 19 2740
迷失自我
迷失自我 2021-01-29 18:44

Sometimes, I come across the following interview question: How to implement 3 stacks with one array ? Of course, any static allocation is not a solution.

19条回答
  •  逝去的感伤
    2021-01-29 19:05

    We can generalize it to K stacks in one Array. Basic idea is to:

    • Maintain a PriorityQueue as a min heap of currently free indexes in the allocation array.
    • Maintain an array of size K, that holds the top of the stack, for each of the stacks.
    • Create a Data class with 1) Value 2) Index of Prev element in the allocation array 3) Index of current element being pushed in the allocation array
    • Maintain an allocation array of type Data

    Refer the code for a working sample implementation.

    import java.util.*;
    public class Main 
    { 
        // A Java class to represent k stacks in a single array of size n 
        public static final class KStack {
    
          /**
          * PriorityQueue as min heap to keep track of the next free index in the 
          * backing array.
          */
          private final PriorityQueue minHeap = new PriorityQueue<>((a,b) -> (a - b));
    
          /**
          * Keeps track of the top of the stack of each of the K stacks
          */
          private final Data index[];
    
          /**
          * Backing array to hold the data of K stacks.
          */
          private final Data array[];
    
          public KStack(int noOfStacks, int sizeOfBackingArray) {
            index = new Data[noOfStacks];
            array = new Data[sizeOfBackingArray];
    
            for(int i =0; i< sizeOfBackingArray; i++) {
              minHeap.add(i);
            }
          }
    
    
          public void push(int val, int stackNo) {
            if(minHeap.isEmpty()) {
              return;
            }
    
            int nextFreeIdx = minHeap.poll();
            Data tos = index[stackNo];
            if(tos == null) {
              tos = new Data(val, -1 /* Previous elemnet's idx*/, nextFreeIdx
                            /* This elemnent's idx in underlying array*/);
            } else {
              tos = new Data(val, tos.myIndex, nextFreeIdx);
            }
    
            index[stackNo] = tos;
            array[nextFreeIdx] = tos;
          }
    
          public int pop(int stackNo) {
            if(minHeap.size() == array.length) {
              return -1; // Maybe throw Exception?
            }
    
            Data tos = index[stackNo];
            if(tos == null) {
              return -1; // Maybe throw Exception?
            }
    
            minHeap.add(tos.myIndex);
            array[tos.myIndex] = null;
    
            int value = tos.value;
            if(tos.prevIndex == -1) {
              tos = null;
            } else {
              tos = array[tos.prevIndex];
            }
    
            index[stackNo] = tos;
            return value;
          }
        }
    
       public static final class Data {
         int value;
         int prevIndex;
         int myIndex;
    
         public Data(int value, int prevIndex, int myIndex) {
           this.value = value;
           this.prevIndex = prevIndex;
           this.myIndex = myIndex;
         }
    
         @Override
         public String toString() {
           return "Value: " + this.value + ", prev: " + this.prevIndex + ", myIndex: " + myIndex; 
         }
       }
    
        // Driver program 
        public static void main(String[] args) 
        { 
            int noOfStacks = 3, sizeOfBackingArray = 10; 
    
            KStack ks = new KStack(noOfStacks, sizeOfBackingArray); 
    
            // Add elements to stack number 1
            ks.push(11, 0); 
            ks.push(9, 0); 
            ks.push(7, 0); 
    
        // Add elements to stack number 3
            ks.push(51, 2); 
            ks.push(54, 2); 
    
            // Add elements to stack number 2
            ks.push(71, 1); 
            ks.push(94, 1); 
            ks.push(93, 1); 
    
    
            System.out.println("Popped from stack 3: " + ks.pop(2)); 
            System.out.println("Popped from stack 3: " + ks.pop(2)); 
            System.out.println("Popped from stack 3: " + ks.pop(2)); 
            System.out.println("Popped from stack 2: " + ks.pop(1)); 
            System.out.println("Popped from stack 1: " + ks.pop(0)); 
        } 
    } 
    

提交回复
热议问题