Skip to content

LeetCode 每日一题笔记 ​

0. 前言 ​

  • 日期:2026.06.20
  • 题目:3754. 连接非零数字并乘以其数字和 I
  • 难度:简单
  • 标签:数学、字符串、数字拆解

1. 题目理解 ​

问题描述 给定整数 n,处理规则:

  1. 提取 n 中全部非零数字,保持原有顺序拼接成新整数 x;无任何非零数字则 x=0;
  2. sum 为 x 所有数字相加的和;
  3. 返回 x * sum 的结果。

示例

输入:n = 10203004 输出:12340 解释:非零数字为1、2、3、4,拼接得x=1234,sum=1+2+3+4=10,1234*10=12340。

2. 解题思路 ​

核心观察 ​

  1. 字符串解法:直接转字符串遍历字符,筛选非0字符同时累加数字和;
  2. 纯数学优化解法:通过取模、整除逐位拆解数字,反向记录非零数字,最后反转得到正确顺序,全程不使用字符串,消除字符相关if分支;
  3. 边界:不存在非零数字时直接返回0。

算法步骤 ​

字符串原版:

  1. 数字转为字符串;
  2. 遍历每个字符,非0则拼接、累加数字和;
  3. 无拼接字符直接返回0;
  4. 拼接字符串转long,与sum相乘返回。

数学优化版:

  1. 循环取模分离每一位数字;
  2. 仅保留非0数字,用变量记录拼接基数、数字总和;
  3. 反向存储的数字反转得到正确顺序x;
  4. 计算 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. 复杂度分析 ​

  • 字符串原版 时间复杂度:O(L),L为数字位数,存在字符判空、字符是否为0两层if分支,涉及字符串对象创建 空间复杂度:O(L),StringBuilder存储字符,占用额外字符串内存
  • 纯数学优化版 时间复杂度:O(L),仅两次数字遍历,消除字符串相关分支与对象操作 空间复杂度:O(1),仅常数long/int变量,无容器占用内存

6. 总结 ​

  • 核心:筛选非0数字,同时统计数字和,最后做乘积;
  • 优化亮点:舍弃字符串处理,纯数学取模拆解数字,减少字符判断if分支,降低内存开销;
  • 关键点:数字拆解后顺序颠倒,需要二次反转还原原始数字顺序。

Powered by VitePress 1.6.4 | 持续更新中