算法题解 - 牛客编程巅峰赛S1第2场 - 青铜&白银组

A. 牛牛扔牌

题目描述

牛牛现在有 n 张扑克牌,每张扑克牌都有点数和花色两部分组成。点数为 ‘1’ - ‘9’ 的正整数,花色为 ‘C’, ‘D’, ‘H’, ‘S’ 其中的一个,分别表示梅花、方块、红桃、黑桃。现在牛牛想按一定的顺序把这n张牌扔掉。扔牌顺序的规则如下:

  1. 如果现在还剩素数张牌,则将牌顶的牌扔掉

  2. 如果现在还剩非素数张牌,则将牌底的牌扔掉

牛牛想知道他的扔牌顺序是什么,请返回扔牌顺序的字符串

备注:

对于 100% 的数据,1 ≤ n ≤ 10。

示例1

输入

"3C8D6H3D"

输出

"3D3C8D6H"

说明

开始 n = 4,为非素数,扔掉牌底的牌 3D
n = 3,为素数,扔掉牌顶的牌 3C
n = 2,为素数,扔掉牌顶的牌 8D
n = 1,为非素数,扔掉牌底的牌 6H

示例2

输入

"8S8S8S8S8S8S8S"

输出

"8S8S8S8S8S8S8S"

说明

因为全是8S,所以扔牌顺序的每一张牌也都是8S

解法

思路分析

由于 n 在 [1, 10] 上,故本题直接把所有素数列出来即可。没什么难度。

时间复杂度:O(n)

空间复杂度:O(n)

代码实现

/**
 * 
 * @param x string字符串 字符串从前到后分别是从上到下排列的n张扑克牌
 * @return string字符串
 */
public String Orderofpoker (String x) {
   
    int n = x.length() / 2;
    int top = 0, bot = x.length() - 2;
    String res = "";
    while(n > 0){
   
        if(n == 2 || n == 3 || n == 5 || n == 7){
   
            res += x.substring(top, top + 2);
            top += 2;
        }else{
   
            res += x.substring(bot, bot + 2);
            bot -= 2;
        }
        n--;
    }
    return res;
}

B. 疯狂过山车

题目描述

今天牛牛去游乐园玩过山车项目,他觉得过山车在上坡下坡的过程是非常刺激的,回到家之后就受到启发,想到了一个问题。如果把整个过山车的轨道当作是一个长度为 n 的数组 num,那么在过山车上坡时数组中的值是呈现递增趋势的,到了最高点以后,数组中的值呈现递减的趋势,牛牛把符合这样先增后减规律的数组定义为金字塔数组,请你帮牛牛在整个 num 数组中找出长度最长的金字塔数组,如果金字塔数组不存在,请输出 0。

备注:

1 <= n <= 1000000,且 num 数组中的数 0 <= num[i] <= 1000000。

示例1

输入

4,[1,2,3,1]

输出

4

示例2

输入

5,[1,5,3,3,1]

输出

3

解法一:直观解法

思路分析

在遍历的时候判断是否是金字塔数组即可。当前数字 i 和前一个数字 j 比较有三种情况:

  1. i > j,说明数组处于爬升阶段,若 j 是低谷则对长度 len 初始化为 1。len++。
  2. i = j,必定不是金字塔,初始化 len 为 1。
  3. i < j,若之前处于爬升阶段,说明是金字塔,len++,并且和金字塔最大长度 res 作比较。

时间复杂度:O(n)

空间复杂度:O(1)

代码实现

/**
 * 
 * @param n int整型 
 * @param num int整型一维数组 
 * @return int整型
 */
public int getMaxLength (int n, int[] num) {
   
  // write code here
  int res = 0;
  int len = 1;
  boolean up = false;
  for(int i = 1; i < n; i++) {
   
    if(num[i] > num[i - 1]) {
   
      up = true;
      if(i > 1 && num[i - 1] < num[i - 2]) len = 1;
      len++;
    }else if(num[i] == num[i - 1]) {
   
      len = 1;
      up = false;
    }else {
   
      if(up) {
   
        len++;
        res = Math.max(len, res);
      }
    }
  }
  return res;
}

解法二:寻找金字塔顶法

思路分析

金字塔数组长度 = 爬升阶段长度 + 1 (塔顶) + 下降阶段长度。

下降阶段相当于从右往左遍历时的爬升阶段

因此分别用 l 数组r 数组记录从左到右从右到左的爬升阶段长度。

若 l[i] 和 r[i] 都不为 0,说明 i 是塔顶。

时间复杂度:O(n)

空间复杂度:O(n)

代码实现

/**
 * 
 * @param n int整型 
 * @param num int整型一维数组 
 * @return int整型
 */
public int getMaxLength (int n, int[] num) {
   
  int res = 0;
  int[] l =
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值