AI刷题120. 字符串字符类型排序问题 | 豆包MarsCode AI 刷题

32 阅读4分钟

120. 字符串字符类型排序问题

问题描述

小C 需要对一个字符串进行特殊排序,这个字符串只包含三种字符类型:字母(大小写)、数字和问号。要求你按照以下规则进行排序:

  1. 问号的原始位置必须保持不变。
  2. 数字的原始位置必须保持不变,但数字要按照从大到小排序。
  3. 字母的原始位置必须保持不变,但字母要按照字典序从小到大排序。

你需要编写一个程序,帮助小C实现这个字符串的排序功能。

题目链接:www.marscode.cn/practice/36…

思路解析

  1. 问号位置的保留

    • 由于问号的位置需要保持不变,我们可以直接在结果数组中保留问号的位置。
  2. 数字和字母的排序

    • 使用两个列表分别存储数字和字母,方便后续对它们进行排序。
  3. 将排序后的数字和字母放回原来的位置

    • 再次遍历输入字符串,将排序后的数字和字母放回结果数组中对应的位置

解体步骤

  1. 初始化数据结构

    • 创建两个列表 digits 和 letters 分别用于存储数字和字母。
    • 创建一个字符数组 result 用于存储最终的结果。
  2. 第一次遍历

    • 遍历输入字符串,将数字和字母分别存储到 digits 和 letters 列表中,问号直接放入 result 数组中。
  3. 排序

    • 对 digits 列表进行从大到小排序。
    • 对 letters 列表进行字典序排序。
  4. 第二次遍历

    • 再次遍历输入字符串,将排序后的数字和字母放回 result 数组中对应的位置。

复杂度分析

时间复杂度分析

  1. 第一次遍历输入字符串

    • 遍历输入字符串一次,时间复杂度为 O(n),其中 n 是输入字符串的长度。
  2. 对数字和字母进行排序

    • 假设数字的数量为 d,字母的数量为 l,则排序的时间复杂度分别为 O(d log d) 和 O(l log l)
    • 由于 d + l <= n,所以排序的总时间复杂度为 O(n log n)
  3. 第二次遍历输入字符串

    • 再次遍历输入字符串一次,时间复杂度为 O(n)

空间复杂度分析

  1. 存储数字和字母的列表

    • 使用两个列表 digits 和 letters,它们的空间复杂度分别为 O(d) 和 O(l),总的空间复杂度为 O(n)
  2. 结果数组

    • 使用一个字符数组 result,空间复杂度为 O(n)

Code

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static String solution(String inp) {
        // 用于存储数字和字母的位置和内容
        List<Character> digits = new ArrayList<>();
        List<Character> letters = new ArrayList<>();
        char[] result = new char[inp.length()];

        // 遍历输入字符串,将数字和字母分别存储,并保留问号的位置
        for (int i = 0; i < inp.length(); i++) {
            char c = inp.charAt(i);
            if (Character.isDigit(c)) {
                digits.add(c);
            } else if (Character.isLetter(c)) {
                letters.add(c);
            } else {
                result[i] = c; // 问号直接放入结果数组
            }
        }

        // 对数字和字母进行排序
        Collections.sort(digits, Collections.reverseOrder()); // 数字从大到小排序
        Collections.sort(letters); // 字母按字典序排序

        // 将排序后的数字和字母放回原位置
        int digitIndex = 0;
        int letterIndex = 0;
        for (int i = 0; i < inp.length(); i++) {
            if (result[i] == 0) { // 如果当前位置是空的(即不是问号)
                if (Character.isDigit(inp.charAt(i))) {
                    result[i] = digits.get(digitIndex++);
                } else {
                    result[i] = letters.get(letterIndex++);
                }
            }
        }

        return new String(result);
    }

    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(solution("12A?zc").equals("21A?cz"));
        System.out.println(solution("1Ad?z?t24").equals("4Ad?t?z21"));
        System.out.println(solution("???123??zxy?").equals("???321??xyz?"));
    }
}

总结

学到的知识

  1. 字符串处理

    • 如何遍历字符串并根据字符类型进行分类。
    • 如何对不同类型的字符进行排序。
  2. 排序算法

    • 使用 Collections.sort 对列表进行排序。
    • 使用 Collections.reverseOrder 对列表进行逆序排序。
  3. 复杂度分析

    • 理解并分析代码的时间复杂度和空间复杂度。

AI的使用感受

使用AI来解决编程问题可以带来以下几点感受:

  1. 快速获取思路

    • AI能够快速提供解题思路和算法步骤,帮助我们更好地理解问题。
  2. 代码实现辅助

    • AI可以提供代码框架和关键步骤的提示,帮助我们更快地编写代码。
  3. 学习效率提升

    • 通过AI的辅助,我们可以更快地掌握新的编程技巧和算法知识。
  4. 错误排查

    • AI可以帮助我们分析代码的复杂度,并提供优化建议,帮助我们更好地理解代码的性能。