力扣算法 1768. 交替合并字符串

1. 题目描述

  • 题目:

    给你两个字符串 word1word2 。请你从 word1 开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。

    返回 合并后的字符串

  • 输入: 两个字符串 word1word2

  • 输出: 返回合并后的字符串

  • 要求:word1 开始交替取字符拼接;如果某个字符串先用完,把另一个字符串剩余部分直接接到末尾

  • 题目关键点:

    1. "交替"= 轮流各取一个字符(先 word1word2

    2. 两个字符串长度可能不同,短的用完后要把长的剩余全部追加

示例

输入:word1 = "abc", word2 = "pqr"

输出:"apbqcr"

解释:a+p+b+q+c+r


2. 解题思路(先讲人话,再讲算法)

我把题目翻译成大白话就是:

用两个手指分别指着两个字符串,从 word1 先拿一个字符,再从 word2 拿一个字符,重复;谁先拿完,就把另一个剩下的一段直接贴到后面。

然后我们要做到:

  1. 保持交替顺序 :每轮尽量拿 word1[i]、再拿 word2[j]

  2. 处理长度不一致 :如果 i 超界了就不再拿 word1,同理 word2


3. 题解(核心算法)

3.1 为什么用这个方法(为什么不用别的)

  • 为什么可行: 题目就是"按顺序模拟取字符",用两个下标/指针最直观

  • 为什么高效: 每个字符只追加一次,整体一次遍历即可

  • 本题不需要/不允许: 不需要复杂算法,也没必要开额外数组;但为了高效拼接字符串,必须用 StringBuilder(避免频繁创建新字符串)

3.2 关键变量定义(读代码前先认清角色)

  • mword1 的长度

  • nword2 的长度

  • i:指向 word1 当前要取的字符位置

  • j:指向 word2 当前要取的字符位置

  • ansStringBuilder,负责高效拼接答案

3.3 代码(完整可运行,Java)

java 复制代码
class Solution {
    public String mergeAlternately(String word1, String word2) {
        int m = word1.length(), n = word2.length();
        int i = 0, j = 0;

        // 预估容量:最多 m + n 个字符,提前扩容更省事
        StringBuilder ans = new StringBuilder(m + n);

        // 只要任意一个字符串还有字符,就继续
        while (i < m || j < n) {
            if (i < m) {
                ans.append(word1.charAt(i));
                i++;
            }
            if (j < n) {
                ans.append(word2.charAt(j));
                j++;
            }
        }
        return ans.toString();
    }
}

4. 代码逐段/逐行讲解(最重要)

4.1 初始化部分

  • int m = word1.length(), n = word2.length();

    先拿到两个字符串长度,后面做边界判断(是否越界)用得上。

  • int i = 0, j = 0;

    两个指针从 0 开始,分别指向 word1word2 的开头。

  • StringBuilder ans = new StringBuilder(m + n);

    拼接字符串用 StringBuilder,并且给一个容量 m+n,减少扩容次数(性能更稳)。

4.2 主循环部分

  • while (i < m || j < n)
    只要有一个字符串还没读完,就继续循环

    这里用 || 很关键:如果用 &&,一旦短的读完就会提前停止,导致长的剩余丢失。

  • 第一段:

    java 复制代码
    if (i < m) {
        ans.append(word1.charAt(i));
        i++;
    }
  • 含义:如果 word1 还有字符,就取一个加入答案,然后 i 往后走一格。

  • 第二段:

    java 复制代码
    if (j < n) {
        ans.append(word2.charAt(j));
        j++;
    }
  • 含义:同理,如果 word2 还有字符,也取一个加入答案,然后 j++

  • 你可以把每一轮想象成"一次尽量做两件事:先拿 word1 的一个,再拿 word2 的一个;谁没得拿就跳过"。

    4.3 返回值部分

  • return ans.toString();

  • StringBuilder 最终转回 String,就是答案。

5. 本题相关知识点补充

5.1 什么是"双指针"

定义:用两个索引/指针同时在两个位置移动 ,常用于合并、比较、滑动窗口等场景。

本题属于:同向双指针(并行推进) ------ iword1jword2


5.2 为什么拼接字符串要用 StringBuilder(StringBuilder 是什么)

一句话定义: StringBuilder 是 Java 里用来高效拼接字符串的可变容器。

为什么要用它?

在 Java 中,String不可变对象 (immutable)。你每做一次 + 拼接,都会:

  1. 创建一个新字符串

  2. 把旧字符串内容复制过去

  3. 再把新字符追加进去

当拼接次数多时,这种反复"创建 + 复制"会变慢。

而 StringBuilder 的优势:

  • 它内部像一个"可增长的字符缓冲区"

  • append 时尽量在同一个容器里扩展

  • 更适合本题这种"不断往结果末尾加字符"的场景

✅ 本题推荐写法:

java 复制代码
StringBuilder ans = new StringBuilder(m + n);

m + n 作为预估容量,能减少扩容次数,性能更稳。


5.3 什么是 ans.append(...)(append 的含义)

一句话理解: append 就是"把内容追加到末尾"。

在本题里:

  • ans 是一个 StringBuilder,用来存"正在拼的答案"

  • ans.append(x) 表示:把 x 接到 ans 的末尾

例如:

java 复制代码
ans.append('a'); // ans: "a"
ans.append('p'); // ans: "ap"
ans.append('b'); // ans: "apb"

在题目的代码中:

java 复制代码
ans.append(word1.charAt(i));

意思就是:把 word1 的第 i 个字符追加到结果末尾

最后用:

java 复制代码
ans.toString()

StringBuilder 转回 String 作为最终答案返回。


5.4 易错点

  1. 循环条件写错 :应是 while (i < m || j < n),不是 &&

  2. 忘记处理剩余部分 :其实剩余部分就是在 while + if 里自然追加完成的

  3. 用 String 直接拼接ans = ans + ... 会频繁创建新字符串,建议用 StringBuilder

6. 复杂度分析

  • 时间复杂度: O(m + n)(每个字符最多被处理一次)

  • 空间复杂度: O(m + n)(结果字符串本身需要这么多空间;额外工作空间是 O(1)


7. 总结

本题一句话总结:两个指针从头开始走,循环中按顺序各追加一个字符,谁先走完就只追加另一个的剩余。

你学到的技巧:

  • i/j 双指针做"合并/模拟"

  • StringBuilder 做高效字符串拼接

  • 循环条件用 || 才不会漏掉剩余部分

类似题推荐(同类"字符串处理/模拟"思路):

  • 1662 比较字符串数组是否相等(拼接/遍历思想)

  • 1071 字符串的最大公因子(字符串规律)

  • 1704 判断字符串的两半是否相似(计数/遍历)


8. 扩展写法

扩展 1:按 "轮数" 遍历(更像按节拍交替)

思路:从 k = 0max(m, n)-1,每轮分别尝试追加 word1[k]word2[k](存在才加)。

优点:写法更"节拍化";缺点:本质一样。

相关推荐
naruto_lnq4 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq4 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
qq_297574674 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端
老毛肚4 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
学嵌入式的小杨同学4 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
lang201509284 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
Re.不晚4 小时前
Java入门17——异常
java·开发语言
爱吃rabbit的mq5 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
缘空如是5 小时前
基础工具包之JSON 工厂类
java·json·json切换