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

45 阅读3分钟

问题描述

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

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

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


测试样例

样例1:

输入:inp = "12A?zc"
输出:'21A?cz'

样例2:

输入:inp = "1Ad?z?t24"
输出:'4Ad?t?z21'

样例3:

输入:inp = "???123??zxy?"
输出:'???321??xyz?'

要实现这个排序规则,我们可以分别提取字母和数字,然后对其排序,最后按照原始字符串的问号、数字和字母位置插入排序后的结果。


解题思路:

  1. 遍历字符串

    • 字母 收集到一个列表 letters
    • 数字 收集到一个列表 numbers
    • 保留问号的位置(直接跳过问号)。
  2. 对字母和数字排序

    • letters 按字典序升序排序。
    • numbers 按从大到小排序。
  3. 重新插入字符

    • 按照字符串的原始位置重新组装字符串。
    • 如果当前字符是问号,直接插入。
    • 如果是数字或字母,从排序好的列表中取出。

样例分析

"1Ad?z?t24"

输入解析:

字符串包含:

  • 数字:1, 2, 4
  • 字母:A, d, z, t
  • 问号:?, ?

步骤:

  1. 提取数字和字母

    • 数字列表:[1, 2, 4]
    • 字母列表:['A', 'd', 'z', 't']
  2. 排序

    • 数字按降序:[4, 2, 1]
    • 字母按字典序:['A', 'd', 't', 'z']
  3. 重建字符串

    • 遍历原字符串:

      • 遇到 1:插入排序后的数字 4
      • 遇到 A:插入排序后的字母 A
      • 遇到 d:插入排序后的字母 d
      • 遇到 ?:保留问号。
      • 遇到 z:插入排序后的字母 t
      • 遇到 ?:保留问号。
      • 遇到 t:插入排序后的字母 z
      • 遇到 2:插入排序后的数字 2
      • 遇到 4:插入排序后的数字 1

输出:"4Ad?t?z21"

代码实现(java版)

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

public class Main {
    public static String solution(String inp) {
        // Edit your code here
        List<Character> letters = new ArrayList<>();
        List<Character> numbers = new ArrayList<>();

        for (char ch : inp.toCharArray()) {
            if (Character.isLetter(ch)) {
                letters.add(ch);
            } else if (Character.isDigit(ch)) {
                numbers.add(ch);
            }
        }

        letters.sort(Character::compareTo); 
        numbers.sort((a, b) -> b - a);      

        StringBuilder result = new StringBuilder();
        int letterIndex = 0, numberIndex = 0;

        for (char ch : inp.toCharArray()) {
            if (ch == '?') {
                result.append('?'); 
            } else if (Character.isLetter(ch)) {
                result.append(letters.get(letterIndex++)); 
            } else if (Character.isDigit(ch)) {
                result.append(numbers.get(numberIndex++)); 
            }
        }

        return result.toString();
    }

    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?"));
    }
}

复杂度分析:

  • 时间复杂度

    • 遍历字符串:O(n)O(n)O(n)。
    • 排序字母和数字:O(klog⁡k)O(k \log k)O(klogk) 和 O(mlog⁡m)O(m \log m)O(mlogm)(其中 kkk 是字母的数量,mmm 是数字的数量)。
    • 总计:O(n+klog⁡k+mlog⁡m)O(n + k \log k + m \log m)O(n+klogk+mlogm)。
  • 空间复杂度

    • 存储字母和数字列表:O(k+m)O(k + m)O(k+m)。