题目
题目链接
解题思路
完整思路:
- 使用 \(HashMap\) 统计每个数字出现次数
- 将统计结果按照出现次数和数字大小排序
- 根据最小出现次数的数字情况分类处理:
- 如果最小次数为 \(0\),需要特殊处理
- 如果最小次数的是 \(0\),使用次小的数字
- 否则使用最小次数的数字重复
代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;int main() {string s;cin >> s;// 初始化计数数组vector<pair<int, int>> digitCount;for(int i = 0; i < 10; i++) {digitCount.push_back({i, 0});}// 统计每个数字出现次数for(char c : s) {digitCount[c - '0'].second++;}// 按照出现次数和数字大小排序sort(digitCount.begin(), digitCount.end(), [](const pair<int, int>& a, const pair<int, int>& b) {if(a.second == b.second) return a.first < b.first;return a.second < b.second;});// 获取最小和次小出现次数的数字auto firstEntry = digitCount[0];auto secondEntry = digitCount[1];string result;if(firstEntry.second == 0) {// 如果最小次数为0if(firstEntry.first == 0) {if(secondEntry.second == 0) {result = to_string(secondEntry.first);} else {result = "10";}} else {result = to_string(firstEntry.first);}} else {// 如果最小次数不为0if(firstEntry.first == 0) {// 使用次小的数字for(int i = 0; i <= secondEntry.second; i++) {result += to_string(secondEntry.first);}} else {// 使用最小的数字for(int i = 0; i <= firstEntry.second; i++) {result += to_string(firstEntry.first);}}}cout << result << endl;return 0;
}
import java.util.*;public class Main {private static HashMap<Integer, Integer> digitMap = new HashMap<Integer, Integer>() {{for(int i = 0; i < 10; i++) {put(i, 0);}}};public static void main(String[] args) {Scanner in = new Scanner(System.in);while(in.hasNext()) {solution(in);}}private static void solution(Scanner in) {String digits = in.nextLine();// 统计每个数字出现次数for(char ch : digits.toCharArray()) {int digit = ch - '0';digitMap.put(digit, digitMap.get(digit) + 1);}// 将统计结果转换为列表并排序List<Map.Entry<Integer, Integer>> digitCountList = new ArrayList<>(digitMap.entrySet());Collections.sort(digitCountList, (o1, o2) -> {if(o1.getValue().equals(o2.getValue())) {return o1.getKey() - o2.getKey();} else {return o1.getValue() - o2.getValue();}});// 获取最小和次小出现次数的数字Map.Entry<Integer, Integer> firstEntry = digitCountList.get(0);Map.Entry<Integer, Integer> secondEntry = digitCountList.get(1);StringBuilder sb = new StringBuilder();if(firstEntry.getValue() == 0) {// 如果最小次数为0if(firstEntry.getKey() == 0) {if(secondEntry.getValue() == 0) {sb.append(secondEntry.getKey());} else {sb.append(10);}} else {sb.append(firstEntry.getKey());}} else {// 如果最小次数不为0if(firstEntry.getKey() == 0) {// 使用次小的数字for(int i = 0; i <= secondEntry.getValue(); i++) {sb.append(secondEntry.getKey());}} else {// 使用最小的数字for(int i = 0; i <= firstEntry.getValue(); i++) {sb.append(firstEntry.getKey());}}}System.out.println(sb);// 重置计数for(int i = 0; i < 10; i++) {digitMap.put(i, 0);}}
}
def solve():digits = input().strip()# 初始化计数字典digit_map = {i: 0 for i in range(10)}# 统计每个数字出现次数for ch in digits:digit_map[int(ch)] += 1# 将统计结果转换为列表并排序digit_count_list = list(digit_map.items())digit_count_list.sort(key=lambda x: (x[1], x[0]))# 获取最小和次小出现次数的数字first_entry = digit_count_list[0]second_entry = digit_count_list[1]result = []if first_entry[1] == 0:# 如果最小次数为0if first_entry[0] == 0:if second_entry[1] == 0:result.append(str(second_entry[0]))else:result.append("10")else:result.append(str(first_entry[0]))else:# 如果最小次数不为0if first_entry[0] == 0:# 使用次小的数字result.extend([str(second_entry[0])] * (second_entry[1] + 1))else:# 使用最小的数字result.extend([str(first_entry[0])] * (first_entry[1] + 1))print("".join(result))if __name__ == "__main__":solve()
算法及复杂度
- 算法:排序 + 模拟
- 时间复杂度:\(\mathcal{O}(n \log n)\),主要是排序的复杂度
- 空间复杂度:\(\mathcal{O}(1)\),只需要固定大小的数组或哈希表