主题切换
LeetCode 每日一题笔记
0. 前言
- 日期:2026.06.20
- 题目:3754. 连接非零数字并乘以其数字和 I
- 难度:简单
- 标签:数学、字符串、数字拆解
1. 题目理解
问题描述 给定整数 n,处理规则:
- 提取 n 中全部非零数字,保持原有顺序拼接成新整数 x;无任何非零数字则 x=0;
- sum 为 x 所有数字相加的和;
- 返回
x * sum的结果。
示例
输入:n = 10203004 输出:12340 解释:非零数字为1、2、3、4,拼接得x=1234,sum=1+2+3+4=10,1234*10=12340。
2. 解题思路
核心观察
- 字符串解法:直接转字符串遍历字符,筛选非0字符同时累加数字和;
- 纯数学优化解法:通过取模、整除逐位拆解数字,反向记录非零数字,最后反转得到正确顺序,全程不使用字符串,消除字符相关if分支;
- 边界:不存在非零数字时直接返回0。
算法步骤
字符串原版:
- 数字转为字符串;
- 遍历每个字符,非0则拼接、累加数字和;
- 无拼接字符直接返回0;
- 拼接字符串转long,与sum相乘返回。
数学优化版:
- 循环取模分离每一位数字;
- 仅保留非0数字,用变量记录拼接基数、数字总和;
- 反向存储的数字反转得到正确顺序x;
- 计算 x * sum 返回。
3. 代码实现
java
package lc3754;
class Solution {
public long sumAndMultiply(int n) {
String s = String.valueOf(n);
StringBuilder sb = new StringBuilder();
int sum=0;
for (int i = 0; i < s.length(); i++) {
char c =s.charAt(i);
if (c!='0'){
sb.append(c);
sum += c-'0';
}
}
if (sb.isEmpty()){
return 0;
}
return Long.valueOf(sb.toString())*sum;
}
}4. 代码优化说明
java
class Solution {
public long sumAndMultiply(int n) {
long revX = 0;
int sum = 0;
// 逐位拆解数字,无字符串操作
while(n > 0) {
int digit = n % 10;
n /= 10;
if(digit != 0) {
revX = revX * 10 + digit;
sum += digit;
}
}
// 反转得到原始顺序的x,循环无多余if判断
long x = 0;
for(long tmp = revX; tmp > 0; tmp /= 10) {
x = x * 10 + tmp % 10;
}
return x * sum;
}
}5. 复杂度分析
- 字符串原版 时间复杂度:
,L为数字位数,存在字符判空、字符是否为0两层if分支,涉及字符串对象创建 空间复杂度: ,StringBuilder存储字符,占用额外字符串内存 - 纯数学优化版 时间复杂度:
,仅两次数字遍历,消除字符串相关分支与对象操作 空间复杂度: ,仅常数long/int变量,无容器占用内存
6. 总结
- 核心:筛选非0数字,同时统计数字和,最后做乘积;
- 优化亮点:舍弃字符串处理,纯数学取模拆解数字,减少字符判断if分支,降低内存开销;
- 关键点:数字拆解后顺序颠倒,需要二次反转还原原始数字顺序。