【LeetCode每日一题】——950.按递增顺序显示卡牌

一【题目类别】

  • 队列

二【题目难度】

  • 中等

三【题目编号】

  • 950.按递增顺序显示卡牌

四【题目描述】

  • 牌组中的每张卡牌都对应有一个唯一的整数。你可以按你想要的顺序对这套卡片进行排序。
  • 最初,这些卡牌在牌组里是正面朝下的(即,未显示状态)。
  • 现在,重复执行以下步骤,直到显示所有卡牌为止:
    • 从牌组顶部抽一张牌,显示它,然后将其从牌组中移出。
    • 如果牌组中仍有牌,则将下一张处于牌组顶部的牌放在牌组的底部。
    • 如果仍有未显示的牌,那么返回步骤 1。否则,停止行动。
  • 返回能以递增顺序显示卡牌的牌组顺序。
  • 答案中的第一张牌被认为处于牌堆顶部。

五【题目示例】

  • 示例:
    • 输入:[17,13,11,2,3,5,7]
    • 输出:[2,13,3,11,5,17,7]
    • 解释:
      • 我们得到的牌组顺序为 [17,13,11,2,3,5,7](这个顺序不重要),然后将其重新排序。
      • 重新排序后,牌组以 [2,13,3,11,5,17,7] 开始,其中 2 位于牌组的顶部。
      • 我们显示 2,然后将 13 移到底部。牌组现在是 [3,11,5,17,7,13]。
      • 我们显示 3,并将 11 移到底部。牌组现在是 [5,17,7,13,11]。
      • 我们显示 5,然后将 17 移到底部。牌组现在是 [7,13,11,17]。
      • 我们显示 7,并将 13 移到底部。牌组现在是 [11,17,13]。
      • 我们显示 11,然后将 17 移到底部。牌组现在是 [13,17]。
      • 我们展示 13,然后将 17 移到底部。牌组现在是 [17]。
      • 我们显示 17。
      • 由于所有卡片都是按递增顺序排列显示的,所以答案是正确的。

六【解题思路】

  • 这道题的解法很巧妙,利用了队列的思想,但是存的却是下标,而不是元素
  • 我们将全部的元素下标入队列
  • 然后对原数组从小到大排序,因为题目要求递增
  • 然后遍历排序好的数组,将其按照队列中的下标存到结果数组中,注意是隔一个下标存一个,还要记得题目要求,存完一个之后,将它后面的下标放到队列的最后,为下一轮做准备
  • 其实可以这么看:[0,1,2,3,4,……]中,0存放第一小的元素,2存放第二小的元素,4存放第三小的元素……,而1,3,……就是下一轮了,同样也是递增的
  • 所以我们根据下标就可以根据题目要求建立起这个数组了
  • 最后返回结果数组即可

七【题目提示】

  • 1 < = A . l e n g t h < = 1000 1 <= A.length <= 1000 1<=A.length<=1000
  • 1 < = A [ i ] < = 1 0 6 1 <= A[i] <= 10^6 1<=A[i]<=106
  • 对于所有的 i ! = j , A [ i ] ! = A [ j ] 对于所有的 i != j,A[i] != A[j] 对于所有的i!=jA[i]!=A[j]

八【时间频度】

  • 时间复杂度: O ( N l o g N ) O(NlogN) O(NlogN),其中 N N N为牌组大小
  • 空间复杂度: O ( N ) O(N) O(N),其中 N N N为牌组大小

九【代码实现】

  1. Java语言版
package Queue;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class p950_RevealCardsInIncreasingOrder {

    public static void main(String[] args) {
        int[] deck = {17, 13, 11, 2, 3, 5, 7};
        int[] res = deckRevealedIncreasing(deck);
        System.out.println(Arrays.toString(res));
    }

    public static int[] deckRevealedIncreasing(int[] deck) {
        int len = deck.length;
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < len; i++) {
            queue.offer(i);
        }
        int[] res = new int[len];
        Arrays.sort(deck);
        for (int num : deck) {
            res[queue.poll()] = num;
            if (!queue.isEmpty()) {
                queue.offer(queue.poll());
            }
        }
        return res;
    }

}
  1. C语言版
#include<stdio.h>
#include<stdlib.h>

compare(const void *a, const void *b)
{
	return *(int*)a - *(int*)b;
}

int* deckRevealedIncreasing(int* deck, int deckSize, int* returnSize)
{
	int* queue = (int*)malloc(sizeof(int) * (2 * deckSize));
	int rear = 0;
	int front = 0;
	for (int i = 0; i < deckSize; i++) {
		queue[rear++] = i;
	}
	qsort(deck, deckSize, sizeof(deck[0]), compare);
	int* res = (int*)malloc(sizeof(int) * deckSize);
	for (int i = 0; i < deckSize; i++)
	{
		int num = deck[i];
		res[queue[front++]] = num;
		if (front != rear)
		{
			queue[rear++] = queue[front++];
		}
	}
	*returnSize = deckSize;
	return res;
}

/*主函数省略*/

十【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. C语言版
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值