题950、按递增顺序显示卡牌

一、题目

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

在这里插入图片描述

二、思路

首先就是得搞清楚这个输出的原理是啥,然后反向获得数字排序的思路有是啥。

输出的排序的原理:
就是插空排,比如12345678
先定下1-4,然后将剩余的插入每两个数字之间的缝隙,但是要注意剩余的数字插入的顺序是有一定的要求的,要求就是按照上面的方法继续进行插入排序。
综上,也就是一行数字长度不断减半,一直到小于等于2,开始进行插入,最后得到结果。

举个栗子:12345678排序
分割:

次数分割得到的数字串剩余数字串
第1次分割:1_2_3_4_5678
第2次分割:5_6_78

合并:

次数合并得到的数字串合并后的字符串
第1次合并:5 7 6 85768
第2次合并:1 5 2 7 3 6 4 815273648

注意点:要合并的字符串为长度不相等的时候,要将把第一个插入的数字变为要插入的数字串中的最后一个,然后其他的依次后移。也就是这样:

举个栗子:1234567排序
分割:

次数分割得到的数字串剩余数字串
第1次分割:1_2_3_4_567
第2次分割:5_6_7

合并:

次数合并得到的数字串合并后的字符串
第1次合并:5 7 6576
第2次合并:1 6 2 5 3 7 41625374

注意看第二次插入

然后用代码实现上述过程就可以了,其中分割和合并应该是可以放一起的,但是我怕迷,就给分开了,有兴趣继续优化的可以进一步努力。

三、代码

import java.util.ArrayList;

public class T0950 {

    public static void main(String[] args) {

//        int[] deck = { 17,13,11,2,3,5,7 };
        int[] deck = { 1,2,3,4,5 };    //[1,5,2,4,3]
//        int[] deck = { 1,2,3,4 };     //[1,3,2,4]
//        int[] deck = { 1,2,3,4,5,6,7,8,9 };

        for ( int i :  deckRevealedIncreasing( deck ) )
            System.out.print( i +"\t");
    }

    public static int[] deckRevealedIncreasing(int[] deck) {


        if ( deck.length < 3 )
            return deck;
        //排序
        deck = BubbleSorting(deck);
//      for ( int i :  deck )
//          System.out.print( i +"\t");
//      System.out.println();

        //暂存分割后的数组
        ArrayList<int[]> heap = new ArrayList<>();

        //用于存储切割后的字串长度
        double length = deck.length;

        //指针,指向deck中的当前数字
        int count = 0;

        //用来把deck给切割成一个一个的字串,依次减半,到2停止
        while (count < deck.length){

            length = deck.length-count;

            //判断是不是到2了,没有就除有就停止
            if( length>2 )
                length = Math.ceil(length/2);
            else
                length = Math.ceil(length);

            //初始化
            int[] temp = new int[(int)length];
            for ( int i = 0; i < length; i++ ){
                temp[i] = deck[count++];
            }

            //将切好的数组放list中
            heap.add(temp);

        }

        //将切好的数组合并为最终结果
        while ( heap.size() > 1 ){

            int[] nums1 = heap.get(heap.size()-2);
            int[] nums2 = heap.get(heap.size()-1);

            int[] temp = new int[nums1.length + nums2.length ];

            //根据将要合并的两个数组长度是否一样,进行下一步
            //不一样
            if ( nums2.length != nums1.length ){

                for (int i = 0, j = 0; i+j< temp.length; ){
                    temp[i+j] = nums1[i++];
                    if( i+j < temp.length )
                        if( j > 0 ){
                            temp[i+j] = nums2[ j-1 ];
                        }else{
                            temp[i+j] = nums2[ nums2.length == 1 ? 0:nums2.length-1];
                        }

                    j++;
                }

            //一样
            }else {
                for (int i = 0, j = 0; i+j< temp.length; ){
                    temp[i+j] = nums1[i++];
                    if( j < nums2.length )
                        temp[i+j] = nums2[j++];
                }
            }

            //移除已经合并的数组,并将合并后的结果存在list中
            heap.remove(heap.size()-1);
            heap.remove(heap.size()-1);
            heap.add(temp);
        }

        return heap.get(0);
    }

    //冒泡排序
    public static int[] BubbleSorting(int nums[]){

        for( int i = 0; i < nums.length; i++ ){
            for ( int j = 0; j < nums.length-i-1; j++ ){
                if ( nums[ j ] > nums[ j+1 ] ){
                    int temp = nums[ j ];
                    nums[ j ] = nums[ j+1 ];
                    nums[ j+1 ] = temp;
                }
            }
        }

        return nums;
    }
}

  1. 来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/reveal-cards-in-increasing-order
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值