📜  检查数组是否可堆栈排序

📅  最后修改于: 2022-05-13 01:57:09.329000             🧑  作者: Mango

检查数组是否可堆栈排序


给定一个包含 N 个不同元素的数组,其中元素介于 1 和 N 之间,包括两个端点,检查它是否可堆栈排序。如果可以使用临时堆栈 S 将数组 A[] 存储在另一个数组 B[] 中,则称数组 A[] 是可堆栈排序的。

数组上允许的操作是:

  1. 移除数组 A[] 的起始元素并将其压入堆栈。
  2. 移除堆栈 S 的顶部元素并将其附加到数组 B 的末尾。

如果通过执行这些操作可以将 A[] 的所有元素移动到 B[],使得数组 B 按升序排序,则数组 A[] 是堆栈可排序的。

例子:

Input : A[] = { 3, 2, 1 }
Output : YES
Explanation : 
Step 1: Remove the starting element of array A[] 
        and push it in the stack S. ( Operation 1)
        That makes A[] = { 2, 1 } ; Stack S = { 3 }
Step 2: Operation 1
        That makes A[] = { 1 } Stack S = { 3, 2 }
Step 3: Operation 1
        That makes A[] = {} Stack S = { 3, 2, 1 }
Step 4: Operation 2
        That makes Stack S = { 3, 2 } B[] = { 1 }
Step 5: Operation 2
        That makes Stack S = { 3 } B[] = { 1, 2 }
Step 6: Operation 2
        That makes Stack S = {} B[] = { 1, 2, 3 }
  
Input : A[] = { 2, 3, 1}
Output : NO

给定数组 A[] 是 [1, ..., N] 的排列,所以让我们假设最初的 B[] = {0}。现在我们可以观察到:

  1. 如果堆栈为空或当前元素小于堆栈顶部,我们只能将一个元素压入堆栈 S。
  2. 只有当栈顶是我们才能从栈中弹出B[end] + 1因为数组 B[] 将包含 {1, 2, 3, 4, ..., n}。

    如果我们不能推入数组 A[] 的起始元素,那么给定的数组是不可堆栈排序的。

    下面是上述想法的实现:

    C++
    // C++ implementation of above approach.
    #include 
    using namespace std;
      
    // Function to check if A[] is
    // Stack Sortable or Not.
    bool check(int A[], int N)
    {
        // Stack S
        stack S;
      
        // Pointer to the end value of array B.
        int B_end = 0;
      
        // Traversing each element of A[] from starting
        // Checking if there is a valid operation 
        // that can be performed.
        for (int i = 0; i < N; i++) 
        {
            // If the stack is not empty
            if (!S.empty()) 
            {
                // Top of the Stack.
                int top = S.top();
      
                // If the top of the stack is
                // Equal to B_end+1, we will pop it
                // And increment B_end by 1.
                while (top == B_end + 1) 
                {
                    // if current top is equal to
                    // B_end+1, we will increment 
                    // B_end to B_end+1
                    B_end = B_end + 1;
      
                    // Pop the top element.
                    S.pop();
      
                    // If the stack is empty We cannot
                    // further perfom this operation.
                    // Therefore break
                    if (S.empty()) 
                    {
                        break;
                    }
      
                    // Current Top
                    top = S.top();
                }
      
                // If stack is empty
                // Push the Current element
                if (S.empty()) {
                    S.push(A[i]);
                }
                else 
                {
                    top = S.top();
      
                    // If the Current element of the array A[]
                    // if smaller than the top of the stack
                    // We can push it in the Stack.
                    if (A[i] < top) 
                    {
                        S.push(A[i]);
                    }
                    // Else We cannot sort the array
                    // Using any valid operations.
                    else 
                    {
                        // Not Stack Sortable
                        return false;
                    }
                }
            }
            else 
            {
                // If the stack is empty push the current
                // element in the stack.
                S.push(A[i]);
            }
        }
      
        // Stack Sortable
        return true;
    }
      
    // Driver's Code
    int main()
    {
        int A[] = { 4, 1, 2, 3 };
        int N = sizeof(A) / sizeof(A[0]);
        check(A, N)? cout<<"YES": cout<<"NO";   
        return 0;
    }


    Java
    // Java implementation of above approach.
    import java.util.Stack;
      
    class GFG {
      
    // Function to check if A[] is
    // Stack Sortable or Not.
        static boolean check(int A[], int N) {
            // Stack S
            Stack S = new Stack();
      
            // Pointer to the end value of array B.
            int B_end = 0;
      
            // Traversing each element of A[] from starting
            // Checking if there is a valid operation 
            // that can be performed.
            for (int i = 0; i < N; i++) {
                // If the stack is not empty
                if (!S.empty()) {
                    // Top of the Stack.
                    int top = S.peek();
      
                    // If the top of the stack is
                    // Equal to B_end+1, we will pop it
                    // And increment B_end by 1.
                    while (top == B_end + 1) {
                        // if current top is equal to
                        // B_end+1, we will increment 
                        // B_end to B_end+1
                        B_end = B_end + 1;
      
                        // Pop the top element.
                        S.pop();
      
                        // If the stack is empty We cannot
                        // further perfom this operation.
                        // Therefore break
                        if (S.empty()) {
                            break;
                        }
      
                        // Current Top
                        top = S.peek();
                    }
      
                    // If stack is empty
                    // Push the Current element
                    if (S.empty()) {
                        S.push(A[i]);
                    } else {
                        top = S.peek();
      
                        // If the Current element of the array A[]
                        // if smaller than the top of the stack
                        // We can push it in the Stack.
                        if (A[i] < top) {
                            S.push(A[i]);
                        } // Else We cannot sort the array
                        // Using any valid operations.
                        else {
                            // Not Stack Sortable
                            return false;
                        }
                    }
                } else {
                    // If the stack is empty push the current
                    // element in the stack.
                    S.push(A[i]);
                }
            }
      
            // Stack Sortable
            return true;
        }
      
    // Driver's Code
        public static void main(String[] args) {
      
            int A[] = {4, 1, 2, 3};
            int N = A.length;
      
            if (check(A, N)) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
      
        }
    }
    //This code is contributed by PrinciRaj1992


    输出:

    YES
    

    时间复杂度:O(N)。