AI刷题小总结第三弹 | 豆包MarsCodeAI刷题

49 阅读6分钟

1.找出最长的神奇数列

- 问题描述

  • 小F是一个好学的中学生,今天他学习了数列的概念。他在纸上写下了一个由 0 和 1 组成的正整数序列,长度为 n。这个序列中的 1 和 0 交替出现,且至少由 3 个连续的 0 和 1 组成的部分数列称为「神奇数列」。例如,10101 是一个神奇数列,而 1011 不是。现在,小F想知道在这个序列中,最长的「神奇数列」是哪一个。你能帮他找到吗? 如果有多个神奇数列,那么输出最先出现的一个。!

image.png

- 思路

  • 检查初始条件:

    • if (inp[i] != inp[i + 1] && inp[i + 1] != inp[i + 2]):

      • 检查当前位置 i、i + 1 和 i + 2 是否满足 0 和 1 交替出现的条件。
      • 如果满足条件,说明从 i 开始的子序列可能是神奇数列。
  • 扩展子序列:

    • int j = i + 2;:

      • 初始化 j 为 i + 2,表示从 i + 2 开始继续检查。
    • while (j < len && inp[j] != inp[j - 1]):

      • 循环检查 inp[j] 和 inp[j - 1] 是否不相等(即 0 和 1 交替出现)。
      • 如果相等,说明交替结束,退出循环。
      • ++j;:每次循环 j 增加 1,继续检查下一个字符。
  • 计算当前子序列长度:

    • int current_length = j - i;:

      • 计算从 i 到 j 的子序列长度。
  • 更新最长子序列:

    • if (current_length > max_length):

      • 如果当前子序列长度 current_length 大于 max_length,则更新 max_length 和 max。
    • max_length = current_length;:

      • 更新 max_length 为当前子序列长度。
    • max = inp.substr(i, current_length);:

      • 更新 max 为当前子序列。
  • 跳过已经检查过的部分:

    • i = j - 2; 将 i 设置为 j - 2,跳过已经检查过的部分,避免重复检查。

- 代码

#include<iostream>
#include <string>
std::string solution(const std::string &inp) {
int len = inp.size();
 if (len < 6)  return "";
 else {
 std::string max = "";
int max_length = 0;
   for (int i = 0; i < len - 2; i++) {
   // 检查从 i 开始的子序列是否是神奇数列

  if (inp[i] != inp[i + 1] && inp[i + 1] != inp[i + 2]) {

  int j = i + 2;

  while (j < len && inp[j] != inp[j - 1]) {
   ++j;
  }

  int current_length = j - i;

  if (current_length > max_length ) {
   max_length = current_length;
   max = inp.substr(i, current_length);
  }
   i = j - 2; // 跳过已经检查过的部分

   }
       }
  return max;
 }
 }
 int main() {
 // Add your test cases here
  std::cout << (solution("0101011101") == "010101") << std::endl;
   return 0;
  }

* 2.DNA序列编辑距离

* 问题描述

  • 小R正在研究DNA序列,他需要一个函数来计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:增加一个碱基、删除一个碱基或替换一个碱基。

image.png

* 思路:

  • 采用动态规划,使用二维数组dp[][]。第一列表示dna1转化成dna2需要的步数,第二列表示dna2转化成dna1需要的步数。l1、l2分别为dna1、dna2的长度。

  • 1.初始化:假设dna1为空,那么dna1转化成dna2需要插入dha2的所有字符,dp[0][j]=j;假设dna2为空,那么dna1转化成dna2需要删除所有字符,即dp[i][0]=i。

  • 2.状态转移:如果 dna1[i-1] == dna2[j-1],那么 dp[i][j] = dp[i-1][j-1],因为不需要任何编辑步骤。

  • 否则,dp[i][j] 可以通过以下三种方式得到:

    • 插入:dp[i][j-1] + 1
    • 删除:dp[i-1][j] + 1
    • 替换:dp[i-1][j-1] + 1
  • 取这三种方式的最小值作为 dp[i][j]。

      public class Main {
    
    *   public static int solution(String dna1, String dna2) {
    
    *   // Please write your code here
    
    *   int l1=dna1.length(),l2=dna2.length();
    
    *   int \[]\[]dp=new int\[l1+1]\[l2+1];
    
    *   for(int i=0;i<=l1;i++){
    
    *   dp\[i]\[0]=i;
    
    *   }
    
    *   for(int j=0;j<=l2;j++){
    
    *   dp\[0]\[j]=j;
    
    *   }
    
    *   for(int i=1;i<=l1;i++){
    
    *   for(int j=1;j<=l2;j++){
    
    *   if(dna1.charAt(i-1)==dna2.charAt(j-1))
    
    *   dp\[i]\[j]=dp\[i-1]\[j-1];
    
    *   else{
    
    *   dp\[i]\[j]=Math.min(dp\[i-1]\[j-1],Math.min(dp\[i-1]\[j],dp\[i]\[j-1]))+1;
    
    *   }
    
    *   }
    
    *   }
    
    *   return dp\[l1]\[l2];
    
    *   }
    
    *   public static void main(String\[] args) {
    
    *   // You can add more test cases here
    
    *   System.out.println(solution("AGCTTAGC", "AGCTAGCT") == 2);
    
    *   System.out.println(solution("AGCCGAGC", "GCTAGCT") == 4);
    
    *   }
    
    *   }
    

3.小M的弹子游戏机挑战

问题描述

  • 小M最近迷上了一款弹子游戏机,规则如下:

  • 玩家可以在版面最上方任意一个位置放置弹珠。弹珠会通过得分点时为玩家赢得分数,目标是获得尽可能高的分数。

  • 弹子游戏机的版面由两种组成要素构成:

  • 钉子(用 -1 表示),当弹珠碰到钉子时,有可能弹射到左下或者右下的位置。

  • 得分点(非负整数),弹珠经过得分点时可以获得对应的分数。

  • 如果弹珠所在的格子为空(即没有钉子或者得分点),弹珠会直接往下落。

  • 小M想知道,在一个给定的版面布局中,他能够获得的最高分数是多少。

  • n 表示版面的高度。

  • m 表示版面的宽度。

  • array 是一个 n x m 的二维数组,其中:

  • -1 表示该位置为钉子;

  • 0 表示该位置为空;

  • 正整数表示该位置为得分点,值为该得分点的分数。

image.png

   public class Main {
*   public static int solution(int n, int m, int\[]\[] array) {

*   // 定义一个二维数组来标记是否访问过某个位置

*   boolean\[]\[] visited = new boolean\[n]\[m];

*   int maxScore = 0;

*   // 遍历起始位置

*   for (int i = 0; i < m; i++) {

*   maxScore = Math.max(maxScore, dfs(i, 0, 0, array, visited));

*   }

*   return maxScore;

*   }

*   public static int dfs(int x, int y, int score, int\[]\[] array, boolean\[]\[] visited) {

*   // 检查是否越界

*   if (x < 0 || x >= array\[0].length || y >= array.length) {

*   return score;

*   }

*   // 标记当前位置已访问

*   visited\[y]\[x] = true;

*   // 根据当前位置的情况进行处理

*   if (array\[y]\[x] == -1) { // 是钉子

*   // 尝试向左下和右下移动

*   int scoreLeft = dfs(x - 1, y + 1, score, array, visited);

*   int scoreRight = dfs(x + 1, y + 1, score, array, visited);

*   visited\[y]\[x] = false; // 回溯,取消访问标记

*   return Math.max(scoreLeft, scoreRight);

*   } else if (array\[y]\[x] > 0) { // 是得分点

*   score += array\[y]\[x];

*   }

*   // 继续向下移动

*   int scoreDown = dfs(x, y + 1, score, array, visited);

*   visited\[y]\[x] = false; // 回溯,取消访问标记

*   return scoreDown;

*   }

*   public static void main(String\[] args) {

*   // Add your test cases here

*   System.out.println(solution(3, 3, new int\[]\[] { { -1, 0, -1 }, { 100, 0, 0 }, { 0, 50, 70 } }) == 50);

*   System.out.println(

*   solution(4, 3, new int\[]\[] { { -1, 0, -1 }, { 0, -1, 0 }, { 50, 100, 70 }, { 80, 200, 50 } }) == 130);

*   }

*   }

4.游戏排名第三大的分数

* 问题描述

  • 小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往届比赛中排名第三的分数,作为自己的目标。具体规则如下:

  • 如果分数中有三个或以上不同的分数,返回其中第三大的分数。

  • 如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。

  • 请你帮小M根据给定的分数数组计算目标分数。

image.png

*   \#include <iostream>
*   \#include <set>

*   \#include <vector>

*   using namespace std;

*   int solution(int n, std::vector<int> nums) {

*   // write code here

*   set<int> a;

*   int res;

*   for (int i = 0; i < n; i++) {

*   a.insert(nums\[i]);

*   }

*   if (a.size() >= 3) {

*   // 反向遍历set,找到第三大的元素

*   auto it = a.rbegin();

*   it++; // 第二大的元素

*   it++; // 第三大的元素

*   return \*it;

*   } else {

*   // 如果不同的分数只有两个或更少,返回最大的分数

*   return \*a.rbegin();

*   }

*   }

*   int main() {

*   std::cout << (solution(3, {3, 2, 1}) == 1) << std::endl;

*   std::cout << (solution(2, {1, 2}) == 2) << std::endl;

*   std::cout << (solution(4, {2, 2, 3, 1}) == 1) << std::endl;

*   return 0;

*   }