2026-05-12:最大的偶数。用go语言,给定一个只由字符 '1' 和 '2' 组成的字符串 s。
你可以从中任意删除一些字符,但剩下的字符的相对顺序必须保持不变。
你需要从所有可能的“删除后字符串”中,找出能表示偶数整数的结果字符串里,数值最大的那个,并返回它。
若所有删除方案都无法组成偶数整数,则返回空字符串 ""。
1 <= s.length <= 100。
s 仅由字符 '1' 和 '2' 组成。
输入: s = "1112"。
输出: "1112"。
解释:
该字符串已经表示了最大的偶数,因此不需要删除任何字符。
题目来自力扣3798。
题目解题过程分步详解
一、分步骤解题过程
步骤1:判断是否存在合法偶数
因为只有字符2是偶数,所以字符串中必须至少有一个'2',才能组成偶数;如果没有'2',直接返回空字符串。
步骤2:确定偶数的核心要求
要让整数是偶数,最终字符串的最后一位必须是'2',这是硬性条件。
步骤3:寻找数值最大的偶数
要让数值最大,需要满足两个关键点:
- 长度最长:保留尽可能多的字符;
- 结尾为2:必须以2结尾(满足偶数要求)。
最优方案: 找到字符串中最后一个出现的'2',保留这个'2',同时保留这个'2'前面的所有字符。 原因:
- 保留最后一个2,能保证前面所有字符都不被丢弃,字符串长度最长;
- 长度最长 → 数值一定最大;
- 结尾是2 → 满足偶数要求。
步骤4:处理结果格式
保留最后一个2及它前面的所有字符后,这个字符串就是答案。
(举例:输入1112,最后一个2是第4位,保留前面所有1+这个2,结果就是1112)
二、对应代码的执行逻辑(文字描述)
代码strings.TrimRight(s, "1")的作用:
- 从字符串的最右侧开始,逐个删除字符
1; - 直到遇到第一个非
1的字符(也就是2)就停止; - 最终结果就是:最后一个2 + 它前面的所有字符,完全符合我们的解题逻辑。
以输入1112为例:
- 字符串右侧第一个字符是
2,不是1,所以不删除任何字符; - 直接返回原字符串
1112。
三、时间复杂度 & 额外空间复杂度
1. 总时间复杂度
O(n),n 是输入字符串的长度。
- 代码核心是
TrimRight函数,它需要从右向左遍历一次字符串,遍历次数最多等于字符串长度; - 整个过程只做了一次线性遍历,没有嵌套循环,因此时间复杂度为线性复杂度 O(n)。
2. 总额外空间复杂度
O(n)
- 代码会创建并返回一个新的字符串存储结果,新字符串的长度最大等于原字符串长度;
- 除了输入和输出字符串外,没有使用其他额外的数据结构,因此额外空间复杂度为 O(n)。
总结
- 解题核心:必须以最后一个2结尾,保留其前面所有字符,得到最长且最大的偶数;
- 时间复杂度:O(n)(线性遍历);
- 额外空间复杂度:O(n)(存储结果字符串)。
Go完整代码如下:
package main
import (
"fmt"
"strings"
)
func largestEven(s string) string {
return strings.TrimRight(s, "1")
}
func main() {
s := "1112"
result := largestEven(s)
fmt.Println(result)
}
Python完整代码如下:
# -*-coding:utf-8-*-
def largest_even(s: str) -> str:
return s.rstrip('1')
if __name__ == "__main__":
s = "1112"
result = largest_even(s)
print(result)
C++完整代码如下:
#include <iostream>
#include <string>
#include <algorithm>
std::string largestEven(const std::string& s) {
// 找到最后一个不是 '1' 的位置
size_t pos = s.find_last_not_of('1');
if (pos == std::string::npos) {
return ""; // 如果全是 '1',返回空字符串
}
return s.substr(0, pos + 1);
}
int main() {
std::string s = "1112";
std::string result = largestEven(s);
std::cout << result << std::endl;
return 0;
}