掘金AI刷题小总结第二篇 | 豆包MarsCode AI刷题

43 阅读5分钟

1.最大矩形面积问题

问题描述

小S最近在分析一个数组 h1,h2,...,hN,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 kk 个相邻元素时,如何计算它们所能形成的最大矩形面积。对于 kk 个相邻的元素,我们定义其矩形的最大面积为:R(k)=k×min(h[i],h[i+1],...,h[i+k−1])R(k)=k×min(h[i],h[i+1],...,h[i+k−1])即,R(k) 的值为这 k 个相邻元素中的最小值乘以 k。现在,小S希望你能帮他找出对于任意 k,R(k) 的最大值。

image.png

思路

用两层循环,外层循环遍历所有可能的k值,内层循环遍历数组,计算每个k对应的矩形面积。计算以 A[i]为起点的k个相邻元素的最小值,计算当前k对应的矩形面积并不断更新最大面积。

代码

 int solution(int n, std::vector<int> A) {
// Edit your code here
int max_area = 0;
// 外层循环遍历所有可能的 k 值
for (int k = 1; k <= n; k++) {
// 内层循环遍历数组,计算每个 k 对应的矩形面积
for (int i = 0; i <= n - k; ++i) {
  // 计算以 A[i] 为起点的 k 个相邻元素的最小值
  int min_height = *std::min_element(A.begin() + i, A.begin() + i + k);
  // 计算当前 k 对应的矩形面积
  int area = k * min_height;
  // 更新最大面积
  if (area > max_area) {
    max_area = area;
  }
}
}
return max_area;
}

2.SQL代码补全功能

问题描述

在开发SQL编辑器时,实现自动补全功能是提高用户体验的重要一环。小C需要实现一个功能,根据用户输入的字符片段,快速从已知的SQL关键字和数据库相关名称中找到所有以该片段开头的候选词,并按字典序输出。

例如,当用户输入 s 时,编辑器需要自动提示以 s 开头的所有可能选项,如 select。如果用户输入 fr,则需要提示 from 和 from_mobile。如果在提示中只有一个选项符合,如输入 from_ 时只提示 from_mobile。

image.png

思路

主要是使用Java的Set和String类,如果字符是以input开头,就把他加入到结果数组中,还要注意格式的要求。

代码

public static String solution(int num, String[] data, String input) {
    // Please write your code here
    Set<String> res = new TreeSet<>(); // 使用TreeSet去重并自动排序
    for (String s : data) {
        if (s.startsWith(input)) {
            res.add(s);
        }
    }
    if (res.isEmpty()) {
        return "-1";
    } else {
        return String.join(",", res);
    }
}

3.数字分组求偶数和

问题描述

小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。 numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369。 image.png

思路

将数组中的每个数转换成字符串,对字符串进行数字的统计,统计出奇数和偶数的个数。能产生偶数的组合:奇+奇,偶+偶;能产生奇数的组合:奇+偶。

代码

public static int solution(int[] numbers) {
    // 初始化偶数和奇数的组合数
    int evenWays = 1;
    int oddWays = 0;
    // 遍历每一个数字组
    for (int number : numbers) {
        int evenCount = 0;
        int oddCount = 0;
        // 将数字转换为字符串来遍历每一位
        String group = String.valueOf(number);
        // 统计当前组中偶数和奇数的个数
        for (char digit : group.toCharArray()) {
            int num = Character.getNumericValue(digit); // 将字符转换为数字
            if (num % 2 == 0) {
                evenCount++;
            } else {
                oddCount++;
            }
        }
        // 动态规划更新 evenWays 和 oddWays
        int newEvenWays = evenWays * evenCount + oddWays * oddCount;
        int newOddWays = evenWays * oddCount + oddWays * evenCount;
        // 更新 evenWays 和 oddWays 为新的值
        evenWays = newEvenWays;
        oddWays = newOddWays;
    }
    // 返回能够形成偶数和的组合数
    return evenWays;
}

4.环状DNA的最小表示法

问题描述

小C正在研究一种环状的 DNA 结构,它由四种碱基ACGT构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 n 的碱基序列可以有 n 种不同的表示方式。小C的任务是从这些表示中找到字典序最小的序列,即该序列的“最小表示”。例如:碱基序列 ATCA 从不同位置读取可能的表示有 ATCATCAACAATAATC,其中 AATC 是字典序最小的表示。

image.png

思路

分情况讨论:①所有字母都相同:直接返回。②字母不都相同:比较字符串的字典序,返回小的那个。

代码

public static String solution(String dna_sequence) {
    if (allSame(dna_sequence)) {
        return dna_sequence;
    }
    int len = dna_sequence.length();
    String min_str = dna_sequence;
    for (int i = 1; i < len; i++) {
        min_str = compare(min_str, dna_sequence.substring(i) + dna_sequence.substring(0, i));
    }
    return min_str;
}

// 传入两个等长的字符串,比较谁的字典序更小,传出较小的那一位
public static String compare(String str1, String str2) {
    for (int i = 0; i < str1.length(); i++) {
        if (str1.charAt(i) < str2.charAt(i)) {
            return str1;
        } else if (str1.charAt(i) > str2.charAt(i)) {
            return str2;
        } else {
            continue;
        }
    }
    return "";
}

public static boolean allSame(String str) {
    // 判断该字符串中的所有字母都只是同一种字母
    for (int i = 0; i < str.length() - 1; i++) {
        if (str.charAt(i) != str.charAt(i + 1)) {
            return false;
        }
    }
    return true;
}