【Leetcode】1754. Largest Merge Of Two Strings

题目地址:

https://leetcode.com/problems/largest-merge-of-two-strings/

给定两个字符串 s 1 s_1 s1 s 2 s_2 s2,从一个空串 s s s开始,开两个指针 i = j = 0 i=j=0 i=j=0,每一步可以将 s 1 [ i ] s_1[i] s1[i] s 2 [ j ] s_2[j] s2[j]添到 s s s后面,同时 i i i j j j向后挪动一位。问最后得到的最大字典序的 s s s是什么。

如果 s 1 [ i ] > s 2 [ j ] s_1[i]>s_2[j] s1[i]>s2[j],那么显然应该添 s 1 [ i ] s_1[i] s1[i];反之如果 s 1 [ i ] < s 2 [ j ] s_1[i]<s_2[j] s1[i]<s2[j],那么显然应该添 s 2 [ j ] s_2[j] s2[j]。一般地,如果 s 1 [ i ] > s 2 [ j ] s_1[i]>s_2[j] s1[i]>s2[j],那么就应该添 s 1 [ i ] s_1[i] s1[i],反之类似。粗略的原因是这样的,如果 s 1 [ i : i 1 − 1 ] = s 2 [ j : j 1 − 1 ] s_1[i:i_1-1]=s_2[j:j_1-1] s1[i:i11]=s2[j:j11],但是 s 1 [ i 1 ] > s 2 [ j 1 ] s_1[i_1]>s_2[j_1] s1[i1]>s2[j1],先添 s 1 [ i ] s_1[i] s1[i]可以使 s 1 [ i 1 ] s_1[i_1] s1[i1]优先出现在将要添的字符选项里。严格证明可以用反证法。如果此法不优,则按照更优的方法添加字符,当添加到 s 2 [ j 1 ] s_2[j_1] s2[j1]的时候,将更优的方法做一个对称变换(即添 s 1 s_1 s1的时候变为添 s 2 s_2 s2,反之亦然),那么此时就是添 s 1 [ i 1 ] s_1[i_1] s1[i1]了,显然字典序更大。代码如下:

class Solution {
 public:
  string largestMerge(string s1, string s2) {
    string s;
    for (int i = 0, j = 0; i < s1.size() || j < s2.size();)
	  s += bigger(s1, s2, i, j) ? s1[i++] : s2[j++];

    return s;
  }

  bool bigger(string& s1, string& s2, int i, int j) {
    while (i < s1.size() && j < s2.size()) {
      if (s1[i] > s2[j]) return true;
      else if (s1[i] < s2[j]) return false;
      else i++, j++;
    }

    return j == s2.size();
  }
};

时间复杂度 O ( min ⁡ { l s 1 , l s 2 } ( l s 1 + l s 2 ) ) O(\min\{l_{s_1},l_{s_2}\}(l_{s_1}+l_{s_2})) O(min{ls1,ls2}(ls1+ls2)),空间 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值