一、题目
牌组中的每张卡牌都对应有一个唯一的整数。你可以按你想要的顺序对这套卡片进行排序。
最初,这些卡牌在牌组里是正面朝下的(即,未显示状态)。
现在,重复执行以下步骤,直到显示所有卡牌为止:
1、从牌组顶部抽一张牌,显示它,然后将其从牌组中移出。
2、如果牌组中仍有牌,则将下一张处于牌组顶部的牌放在牌组的底部。
3、如果仍有未显示的牌,那么返回步骤 1。否则,停止行动。
返回能以递增顺序显示卡牌的牌组顺序。
答案中的第一张牌被认为处于牌堆顶部。1
二、思路
首先就是得搞清楚这个输出的原理是啥,然后反向获得数字排序的思路有是啥。
输出的排序的原理:
就是插空排,比如12345678
先定下1-4,然后将剩余的插入每两个数字之间的缝隙,但是要注意剩余的数字插入的顺序是有一定的要求的,要求就是按照上面的方法继续进行插入排序。
综上,也就是一行数字长度不断减半,一直到小于等于2,开始进行插入,最后得到结果。
举个栗子:12345678排序
分割:
次数 | 分割得到的数字串 | 剩余数字串 |
---|---|---|
第1次分割: | 1_2_3_4_ | 5678 |
第2次分割: | 5_6_ | 78 |
合并:
次数 | 合并得到的数字串 | 合并后的字符串 |
---|---|---|
第1次合并: | 5 7 6 8 | 5768 |
第2次合并: | 1 5 2 7 3 6 4 8 | 15273648 |
注意点:要合并的字符串为长度不相等的时候,要将把第一个插入的数字变为要插入的数字串中的最后一个,然后其他的依次后移。也就是这样:
举个栗子:1234567排序
分割:
次数 | 分割得到的数字串 | 剩余数字串 |
---|---|---|
第1次分割: | 1_2_3_4_ | 567 |
第2次分割: | 5_6_ | 7 |
合并:
次数 | 合并得到的数字串 | 合并后的字符串 |
---|---|---|
第1次合并: | 5 7 6 | 576 |
第2次合并: | 1 6 2 5 3 7 4 | 1625374 |
注意看第二次插入
然后用代码实现上述过程就可以了,其中分割和合并应该是可以放一起的,但是我怕迷,就给分开了,有兴趣继续优化的可以进一步努力。
三、代码
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;
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reveal-cards-in-increasing-order
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 ↩︎