字符串字符类型排序问题 | 豆包MarsCode AI刷题
题目规则不清,大写字母要排在小写字母前。简单模拟,用队列思想解决。
摘要
本文介绍了如何对一个字符串按指定规则排序。字符串包含字母、数字和问号。排序规则为数字从大到小、字母按字典序从小到大,并且字符类型的位置保持不变。本文包含Python和Go的代码实现,算法时间复杂度为 。
问题描述
在一个仅包含字母、数字和问号的字符串中,需要按如下规则排序:
- 问号位置不变。
- 数字按降序排序。
- 字母按字典序升序排序。
示例
-
输入:
inp = "12A?zc"输出:"21A?cz" -
输入:
inp = "1Ad?z?t24"输出:"4Ad?t?z21" -
输入:
inp = "???123??zxy?"输出:"???321??xyz?"
原理分析
1. 字符分类
遍历字符串,将字符分为三类:数字、大写字母、小写字母,并各自存进一个切片进行自定义的排序。
2. 排序规则
对每个分类的字符按照指定的顺序排序:
- 数字按从大到小排序。
- 字母按字典序从小到大排序。
3. 构建结果字符串
根据原字符串的位置,将排序后的字符填充到对应位置,问号保留不变。用取队头的方式进行取元素放入答案字符串里面,保持元素的排序后的先后顺序不变。在大小写字母的处理上要判断大写字母是否已经消耗完毕,再考虑使用哪一个队列(大写字母或者小写字母)
代码实现
Python代码
from typing import List
def solution(inp: str) -> str:
"""
该函数接收一个字符串 inp,对其中的数字、大小写字母进行排序:
- 数字按降序排列
- 大写字母和小写字母分别按升序排列
返回按照原始字符类型排列好的新字符串
"""
nums = []
chars_up = []
chars_do = []
# 遍历字符串并分类
for ch in inp:
if '0' <= ch <= '9':
nums.append(int(ch))
elif 'A' <= ch <= 'Z':
chars_up.append(ch)
elif 'a' <= ch <= 'z':
chars_do.append(ch)
# 对每个分类分别排序
chars_up.sort()
chars_do.sort()
nums.sort(reverse=True)
# 用于构造最终字符串的列表
ans_str = []
num_index, up_index, do_index = 0, 0, 0
# 根据原始字符类型填充排序后的字符
for ch in inp:
if '0' <= ch <= '9':
ans_str.append(str(nums[num_index]))
num_index += 1
elif 'A' <= ch <= 'Z':
ans_str.append(chars_up[up_index])
up_index += 1
elif 'a' <= ch <= 'z':
ans_str.append(chars_do[do_index])
do_index += 1
else:
ans_str.append('?')
return ''.join(ans_str)
if __name__ == "__main__":
# 测试用例
print(solution("12A?zc") == "21A?cz")
print(solution("1Ad?z?t24") == "4Ad?t?z21")
print(solution("???123??zxy?") == "???321??xyz?")
Go语言代码
package main
import (
"fmt"
"sort"
)
func solution(inp string) string {
nums := []int{}
charsUp := []rune{}
charsDo := []rune{}
// 分类字符
for i := 0; i < len(inp); i++ {
if inp[i] >= '0' && inp[i] <= '9' {
nums = append(nums, int(inp[i]-'0'))
} else if inp[i] >= 'A' && inp[i] <= 'Z' {
charsUp = append(charsUp, rune(inp[i]))
} else if inp[i] >= 'a' && inp[i] <= 'z' {
charsDo = append(charsDo, rune(inp[i]))
}
}
// 排序
sort.Slice(charsUp, func(i, j int) bool {
return charsUp[i] < charsUp[j]
})
sort.Slice(charsDo, func(i, j int) bool {
return charsDo[i] < charsDo[j]
})
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
// 构建结果
ansStr := []rune{}
for i := 0; i < len(inp); i++ {
if inp[i] >= '0' && inp[i] <= '9' {
ansStr = append(ansStr, rune(nums[0]+'0'))
nums = nums[1:]
} else if inp[i] >= 'A' && inp[i] <= 'Z' {
ansStr = append(ansStr, charsUp[0])
charsUp = charsUp[1:]
} else if inp[i] >= 'a' && inp[i] <= 'z' {
ansStr = append(ansStr, charsDo[0])
charsDo = charsDo[1:]
} else {
ansStr = append(ansStr, '?')
}
}
return string(ansStr)
}
func main() {
// 测试用例
fmt.Println(solution("12A?zc") == "21A?cz")
fmt.Println(solution("1Ad?z?t24") == "4Ad?t?z21")
fmt.Println(solution("???123??zxy?") == "???321??xyz?")
}