1. 题目描述
-
题目:
给你两个字符串
word1和word2。请你从word1开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。返回 合并后的字符串 。
-
输入: 两个字符串
word1和word2 -
输出: 返回合并后的字符串
-
要求: 从
word1开始交替取字符拼接;如果某个字符串先用完,把另一个字符串剩余部分直接接到末尾 -
题目关键点:
-
"交替"= 轮流各取一个字符(先
word1再word2) -
两个字符串长度可能不同,短的用完后要把长的剩余全部追加
-
示例
输入:word1 = "abc", word2 = "pqr"
输出:"apbqcr"
解释:a+p+b+q+c+r
2. 解题思路(先讲人话,再讲算法)
我把题目翻译成大白话就是:
用两个手指分别指着两个字符串,从
word1先拿一个字符,再从word2拿一个字符,重复;谁先拿完,就把另一个剩下的一段直接贴到后面。
然后我们要做到:
-
保持交替顺序 :每轮尽量拿
word1[i]、再拿word2[j] -
处理长度不一致 :如果
i超界了就不再拿word1,同理word2
3. 题解(核心算法)
3.1 为什么用这个方法(为什么不用别的)
-
为什么可行: 题目就是"按顺序模拟取字符",用两个下标/指针最直观
-
为什么高效: 每个字符只追加一次,整体一次遍历即可
-
本题不需要/不允许: 不需要复杂算法,也没必要开额外数组;但为了高效拼接字符串,必须用
StringBuilder(避免频繁创建新字符串)
3.2 关键变量定义(读代码前先认清角色)
-
m:word1的长度 -
n:word2的长度 -
i:指向word1当前要取的字符位置 -
j:指向word2当前要取的字符位置 -
ans:StringBuilder,负责高效拼接答案
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 开始,分别指向
word1、word2的开头。 -
StringBuilder ans = new StringBuilder(m + n);拼接字符串用
StringBuilder,并且给一个容量m+n,减少扩容次数(性能更稳)。
4.2 主循环部分
-
while (i < m || j < n)
只要有一个字符串还没读完,就继续循环 。这里用
||很关键:如果用&&,一旦短的读完就会提前停止,导致长的剩余丢失。 -
第一段:
javaif (i < m) { ans.append(word1.charAt(i)); i++; } -
含义:如果
word1还有字符,就取一个加入答案,然后i往后走一格。 -
第二段:
javaif (j < n) { ans.append(word2.charAt(j)); j++; } -
含义:同理,如果
word2还有字符,也取一个加入答案,然后j++。 -
你可以把每一轮想象成"一次尽量做两件事:先拿 word1 的一个,再拿 word2 的一个;谁没得拿就跳过"。
4.3 返回值部分
-
return ans.toString(); -
StringBuilder最终转回String,就是答案。
5. 本题相关知识点补充
5.1 什么是"双指针"
定义:用两个索引/指针同时在两个位置移动 ,常用于合并、比较、滑动窗口等场景。
本题属于:同向双指针(并行推进) ------ i 走 word1,j 走 word2。
5.2 为什么拼接字符串要用 StringBuilder(StringBuilder 是什么)
一句话定义: StringBuilder 是 Java 里用来高效拼接字符串的可变容器。
为什么要用它?
在 Java 中,String 是不可变对象 (immutable)。你每做一次 + 拼接,都会:
-
创建一个新字符串
-
把旧字符串内容复制过去
-
再把新字符追加进去
当拼接次数多时,这种反复"创建 + 复制"会变慢。
而 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 易错点
-
循环条件写错 :应是
while (i < m || j < n),不是&& -
忘记处理剩余部分 :其实剩余部分就是在
while + if里自然追加完成的 -
用 String 直接拼接 :
ans = ans + ...会频繁创建新字符串,建议用StringBuilder
6. 复杂度分析
-
时间复杂度:
O(m + n)(每个字符最多被处理一次) -
空间复杂度:
O(m + n)(结果字符串本身需要这么多空间;额外工作空间是O(1))
7. 总结
本题一句话总结:两个指针从头开始走,循环中按顺序各追加一个字符,谁先走完就只追加另一个的剩余。
你学到的技巧:
-
用
i/j双指针做"合并/模拟" -
用
StringBuilder做高效字符串拼接 -
循环条件用
||才不会漏掉剩余部分
类似题推荐(同类"字符串处理/模拟"思路):
-
1662 比较字符串数组是否相等(拼接/遍历思想)
-
1071 字符串的最大公因子(字符串规律)
-
1704 判断字符串的两半是否相似(计数/遍历)
8. 扩展写法
扩展 1:按 "轮数" 遍历(更像按节拍交替)
思路:从 k = 0 到 max(m, n)-1,每轮分别尝试追加 word1[k] 和 word2[k](存在才加)。
优点:写法更"节拍化";缺点:本质一样。