1754. 构造字典序最大的合并字符串

目录

🚀 字典序最大的合并字符串:贪心策略下的优雅解法

📘 题目描述

🔍 示例说明

示例 1:

🧠 解题思路与分析

为什么用贪心?

💡 解法一:直接贪心 + 切片比较

代码如下:

核心逻辑:

优点:

⚙️ 解法二(可选优化):避免切片比较

⏱ 复杂度分析

📌 总结


🚀 字典序最大的合并字符串:贪心策略下的优雅解法

在字符串处理问题中,“字典序”类的问题经常考察对字符串比较的理解和策略设计能力。今天我们来分析一道有趣的 LeetCode 字符串题:


📘 题目描述

给定两个仅包含小写英文字母的字符串 word1word2,你需要按照下面的规则构造一个新的字符串 merge,使其字典序最大:

构造规则如下:

  • 初始时,merge 是一个空字符串。
  • 每一步,你可以选择:
    • 如果 word1 非空,将其第一个字符附加到 merge 的末尾,并从 word1 中移除;
    • 如果 word2 非空,将其第一个字符附加到 merge 的末尾,并从 word2 中移除;
  • 当两个字符串都为空时,构造完成。
  • 要求:最终构造的 merge 字符串在所有可能的构造方案中,字典序最大。

字典序规则:
两个字符串 ab 的字典序比较方式如下:

  • 从左到右逐个字符比较;
  • 一旦出现不同字符,谁的字符更靠后(如 'd' > 'c'),谁字典序大;
  • 若其中一个是另一个的前缀,较长者字典序更大。

🔍 示例说明

示例 1:

输入:
word1 = "cabaa"
word2 = "bcaaa"

输出:
"cbcabaaaaa"

解释:

步骤如下:
merge = ""
取 word1[0] = 'c' ⇒ merge = "c"
取 word2[0] = 'b' ⇒ merge = "cb"
取 word2[0] = 'c' ⇒ merge = "cbc"
取 word1[0] = 'a' ⇒ merge = "cbca"
取 word1[0] = 'b' ⇒ merge = "cbcab"
剩下 "aaaaa",依次拼接 ⇒ "cbcabaaaaa"

🧠 解题思路与分析

我们希望构造的字符串 字典序尽可能大。要实现这一点,关键在于:

每一步我们都应该从两个字符串中选择“当前剩余部分字典序更大”的那个的首字母来加入 merge。

换句话说,我们不是简单比较 word1[0]word2[0],而是比较 word1[i:]word2[j:] 这两个剩余字符串整体的字典序

为什么用贪心?

因为每一步做出字典序最大的选择,才能保证最终构成的字符串整体最大。


💡 解法一:直接贪心 + 切片比较

代码如下:

class Solution:
    def largestMerge(self, word1: str, word2: str) -> str:
        merge = []
        i, j = 0, 0
        while i < len(word1) and j < len(word2):
            if word1[i:] > word2[j:]:
                merge.append(word1[i])
                i += 1
            else:
                merge.append(word2[j])
                j += 1
        merge.extend(word1[i:])
        merge.extend(word2[j:])
        return ''.join(merge)

核心逻辑:

  • 比较 word1[i:]word2[j:]
  • 哪个剩余字符串更大,就取它的首字母。

优点:

  • 简洁、清晰;
  • Python 字符串切片和比较效率较高,实际表现良好。

⚙️ 解法二(可选优化):避免切片比较

切片会生成新的字符串,尽管 Python 优化得不错,但在极端情况下可能影响性能。我们可以用双指针手动比较剩余部分来避免切片:

class Solution:
    def larger(self, word1, i, word2, j):
        while i < len(word1) and j < len(word2):
            if word1[i] != word2[j]:
                return word1[i] > word2[j]
            i += 1
            j += 1
        return i != len(word1)  # 若 word1 没完,说明它更长 ⇒ 更大

    def largestMerge(self, word1: str, word2: str) -> str:
        i = j = 0
        merge = []
        while i < len(word1) and j < len(word2):
            if self.larger(word1, i, word2, j):
                merge.append(word1[i])
                i += 1
            else:
                merge.append(word2[j])
                j += 1
        merge.extend(word1[i:])
        merge.extend(word2[j:])
        return ''.join(merge)

⏱ 复杂度分析

项目

复杂度

时间复杂度

最坏情况下为 O(n²),因为 word1[i:] > word2[j:]

是 O(n) 操作,最多比较 n 次。但实际中由于提前退出较快,不会达到极限。

空间复杂度

O(n),用于结果字符串 merge


📌 总结

  • 本题核心在于字典序最大策略,使用贪心思想解决;
  • 利用 Python 字符串的切片和比较,可以快速实现;
  • 如果需要进一步优化,可使用双指针避免切片;
  • 这是一个很典型的字符串贪心 + 字典序比较综合问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值