950. Reveal Cards In Increasing Order**

950. Reveal Cards In Increasing Order**

https://leetcode.com/problems/reveal-cards-in-increasing-order/

题目描述

In a deck of cards, every card has a unique integer. You can order the deck in any order you want.

Initially, all the cards start face down (unrevealed) in one deck.

Now, you do the following steps repeatedly, until all cards are revealed:

  1. Take the top card of the deck, reveal it, and take it out of the deck.
  2. If there are still cards in the deck, put the next top card of the deck at the bottom of the deck.
  3. 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.

The first entry in the answer is considered to be the top of the deck.

Example 1:

Input: [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 doesn't 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.

Note:

  • 1 <= A.length <= 1000
  • 1 <= A[i] <= 10^6
  • A[i] != A[j] for all i != j

C++ 实现 1

这种实现参考了 Java Queue Simulation, Step by Step Explanation, 使用队列来模拟题目描述中的过程. 虽然一开始我的想法也是用队列, 但具体怎么用就是想不出来😅

具体做法是:

  1. 对数组从小到大进行排序;
  2. 队列 Q 保存排序后的数组中每个元素的索引
  3. 对于输出序列 res, 从 Q 中弹出索引, 设置好 res[i] 后, 然后再从 Q 中弹出索引并 push 到队列的尾部, 这相当模拟了题目中将下一张牌插入到牌堆底部的行为.

一点感慨: 数组类型的题, 要不就是玩数组的元素, 要不就是玩数组元素对应的索引, 有时候从数组元素的角度出发如果没有什么思路的话, 可以考虑从数组索角度出发考虑问题.

class Solution {
public:
    vector<int> deckRevealedIncreasing(vector<int>& deck) {
        if (deck.size() < 2) return deck;
        std::sort(deck.begin(), deck.end());
        int n = deck.size();
        queue<int> Q;
        vector<int> res(n);
        for (int i = 0; i < n; ++i) Q.push(i);
        for (int i = 0; i < n; ++i) {
            res[Q.front()] = deck[i];
            Q.pop();
            Q.push(Q.front());
            Q.pop();
        }
        return res;
    }
};

C++ 实现 2

下面是我的实现, 没有用到队列, 纯粹是发现规律, 把题目中那个例子的数组生成过程写下来:

A0: 17 ->    []
A1: 13 ->    [17]
A2: 11 ->    [13, 17]
A3: 7  ->    [11, 17, 13]
A4: 5  ->    [7, 13, 11, 17]
A5: 3  ->    [5, 17, 7, 13, 11]
A6: 2  ->    [3, 11, 5, 17, 7, 13]
A7: None ->  [2, 13, 3, 11, 5, 17, 7]

写完之后, 容易发现规律: A{n+1} 的形成方式是, 将 A{n} 中前 n - 1 个元素挪到最后面, 然后再修改 A{n+1}[0]A{n+1}[1] 两个位置的元素. 比如: A7 的形成是将 A6 中前五个元素 [3, 11, 5, 17, 7, 13] 挪到最后面, 然后令 A7[0] 为目前数组遇到的最小值, A7[1]A6 最后一个元素.

这里首先对数组进行从大到小排序, 这和 C++ 实现 1 不同. 然后就是移动数组中的元素. 这个算法比 C++ 实现 1 要慢.

class Solution {
public:
    vector<int> deckRevealedIncreasing(vector<int>& deck) {
        // std::sort(deck.rbegin(), deck.rend());
        if (deck.size() < 2) return deck;
        std::sort(deck.begin(), deck.end(), std::greater<int>());
        int n = deck.size();
        vector<int> res;
        for (int i = 0; i < n; ++i) {
            res.push_back(deck[i]);
            int size = res.size();
            if (size >= 2) {
                int a = res[size - 1], b = res[size - 2];
                std::copy(res.begin(), res.begin() + size - 2, res.begin() + 2);
                res[0] = a;
                res[1] = b;
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值