Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given an integer array deck. There is a deck of cards where every card has a unique integer. The integer on the ith card is deck[i].
You can order the deck in any order you want. Initially, all the cards start face down (unrevealed) in one deck.
You will do the following steps repeatedly until all cards are revealed:
Return an ordering of the deck that would reveal the cards in increasing order.
Note that the first entry in the answer is considered to be the top of the deck.
Example 1:
Input: deck = [17,13,11,2,3,5,7] Output: [2,13,3,11,5,17,7] Explanation: We get the deck in the order [17,13,11,2,3,5,7] (this order does not matter), and reorder it. After reordering, the deck starts as [2,13,3,11,5,17,7], where 2 is the top of the deck. We reveal 2, and move 13 to the bottom. The deck is now [3,11,5,17,7,13]. We reveal 3, and move 11 to the bottom. The deck is now [5,17,7,13,11]. We reveal 5, and move 17 to the bottom. The deck is now [7,13,11,17]. We reveal 7, and move 13 to the bottom. The deck is now [11,17,13]. We reveal 11, and move 17 to the bottom. The deck is now [13,17]. We reveal 13, and move 17 to the bottom. The deck is now [17]. We reveal 17. Since all the cards revealed are in increasing order, the answer is correct.
Example 2:
Input: deck = [1,1000] Output: [1,1000]
Constraints:
1 <= deck.length <= 10001 <= deck[i] <= 106deck are unique.Problem summary: You are given an integer array deck. There is a deck of cards where every card has a unique integer. The integer on the ith card is deck[i]. You can order the deck in any order you want. Initially, all the cards start face down (unrevealed) in one deck. You will do the following steps repeatedly until all cards are revealed: Take the top card of the deck, reveal it, and take it out of the deck. If there are still cards in the deck then put the next top card of the deck at the bottom of the deck. If there are still unrevealed cards, go back to step 1. Otherwise, stop. Return an ordering of the deck that would reveal the cards in increasing order. Note that the first entry in the answer is considered to be the top of the deck.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[17,13,11,2,3,5,7]
[1,1000]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #950: Reveal Cards In Increasing Order
class Solution {
public int[] deckRevealedIncreasing(int[] deck) {
Deque<Integer> q = new ArrayDeque<>();
Arrays.sort(deck);
int n = deck.length;
for (int i = n - 1; i >= 0; --i) {
if (!q.isEmpty()) {
q.offerFirst(q.pollLast());
}
q.offerFirst(deck[i]);
}
int[] ans = new int[n];
for (int i = n - 1; i >= 0; --i) {
ans[i] = q.pollLast();
}
return ans;
}
}
// Accepted solution for LeetCode #950: Reveal Cards In Increasing Order
func deckRevealedIncreasing(deck []int) []int {
sort.Sort(sort.Reverse(sort.IntSlice(deck)))
q := []int{}
for _, v := range deck {
if len(q) > 0 {
q = append([]int{q[len(q)-1]}, q[:len(q)-1]...)
}
q = append([]int{v}, q...)
}
return q
}
# Accepted solution for LeetCode #950: Reveal Cards In Increasing Order
class Solution:
def deckRevealedIncreasing(self, deck: List[int]) -> List[int]:
q = deque()
for v in sorted(deck, reverse=True):
if q:
q.appendleft(q.pop())
q.appendleft(v)
return list(q)
// Accepted solution for LeetCode #950: Reveal Cards In Increasing Order
struct Solution;
use std::collections::VecDeque;
impl Solution {
fn deck_revealed_increasing(mut deck: Vec<i32>) -> Vec<i32> {
deck.sort_unstable();
let mut queue: VecDeque<i32> = VecDeque::new();
let n = deck.len();
for i in (0..n).rev() {
let last = deck[i];
if let Some(bottom) = queue.pop_back() {
queue.push_front(bottom);
}
queue.push_front(last);
}
queue.into_iter().collect()
}
}
#[test]
fn test() {
let deck = vec![17, 13, 11, 2, 3, 5, 7];
let res = vec![2, 13, 3, 11, 5, 17, 7];
assert_eq!(Solution::deck_revealed_increasing(deck), res);
}
// Accepted solution for LeetCode #950: Reveal Cards In Increasing Order
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #950: Reveal Cards In Increasing Order
// class Solution {
// public int[] deckRevealedIncreasing(int[] deck) {
// Deque<Integer> q = new ArrayDeque<>();
// Arrays.sort(deck);
// int n = deck.length;
// for (int i = n - 1; i >= 0; --i) {
// if (!q.isEmpty()) {
// q.offerFirst(q.pollLast());
// }
// q.offerFirst(deck[i]);
// }
// int[] ans = new int[n];
// for (int i = n - 1; i >= 0; --i) {
// ans[i] = q.pollLast();
// }
// return ans;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.