Problem: Piling Up!

Difficulty: Easy

There is a horizontal row of cubes. The length of each cube is given. You need to create a new vertical pile of cubes. The new pile should follow these directions: if cube(i) is on top of cube (j) then sideLength(j) >= sideLength(i)

When stacking the cubes, you can only pick up either the leftmost or the rightmost cube each time. Print “Yes” if it is possible to stack the cubes. Otherwise, print “No”. Do not print the quotation marks.

Input Format

The first line contains a single integer T, the number of test cases.
For each test case, there are 2  lines.
The first line of each test case contains n, the number of cubes.
The second line contains n space separated integers, denoting the sideLengths of each cube in that order.

Constraints
1 <= T <= 5
1 <= n <= 10^5
1 <= sideLength <= 2^31

Output Format

For each test case, output a single line containing either “Yes” or “No” without the quotes.

Sample Input

2
6
4 3 2 1 3 4
3
1 3 2

Sample Output

Yes
No

Explanation

In the first test case, pick in this order: left – 4, right – 4, left – 3, right -3 , left – 2, right – 1.
In the second test case, no order gives an appropriate arrangement of vertical cubes.3  will always come after either 1 or 2.
How to solve:

The problem sounds hard at the beginning, but if we scratch out the problem on papers, we’ll see that it’s not that difficult. From the problem’s description, sideLength(j) >= sideLength(i) if cube(i) is on top of cube(j), this means the new vertical pile of cubes has a mountain-like shape, smaller from bottom to top. As long as there is no cube bigger than the cubes we’ve seen so far, then it’s possible to build up a pile like that.
Example with the output ‘Yes’
[1]Cubes: 4 – 3 – 2 – 1 – 3 – 4 , left = 0, right = len(Cubes) – 1
Let’s say we got a stack, this stack is initialized with the cube have the largest sideLength, so it’s either left or right. In this example it could be left or right, no big deal. Let’s go for left.
stack = [4], left = 1, right = 5

[2]Cubes = 3 – 2 – 1 – 3 – 4
Cubes[left] and Cubes[right] are still smaller than or equal with the top of the stack, so we compare the Cubes[left] and Cubes[right] values. Pick right
stack = [4, 4], left = 1, right = 4

[3]Cubes = 3 – 2 – 1 – 3
Same as [2] but pick left
stack = [4, 4, 3], left = 2, right = 4

[4]Cubes = 2 – 1 – 3
Same as [3], but pick right
stack = [4, 4, 3, 3] , left = 2, right = 3

[5]Cubes = 2 – 1
Same as [4], but pick left
stack = [4, 4, 3, 3, 2], left = 3, right = 3

[6]Cubes = 1
1 still smaller than the top of the stack, and after this last step, left is now bigger than right, so we stop, and print out ‘yes’

The idea is, before we add a new cube onto the stack, check either the cube at left or right is large than the top of the stack, if that’s true, then print no, otherwise, continue until there is no cube. This is a O(n) solution (worst case).

 

Implementation Python 2.7

if __name__ == '__main__':
    t = input()
    for _ in range(t):
        n = input()
        arr = map(int, raw_input().rstrip().split())
        left, right, stack = 0, len(arr)-1, None 
        if arr[left] >= arr[right]:
            stack = [arr[left]]
            left += 1
        else:
            stack = [arr[right]]
            right -= 1
        if len(arr) <= 2:
            print 'Yes'
        else:
            
            while left <= right:
                if arr[left] > stack[-1] or arr[right] > stack[-1]:
                    print 'No'
                    break
                if arr[left] >= arr[right]:
                    stack.append(arr[left])
                    left += 1
                else:
                    stack.append(arr[right])
                    right -= 1
            else:
                print 'Yes'
        

 

Advertisements