LeetCode 2839. 判断通过操作能否让字符串相等 I

LeetCode 2839. 判断通过操作能否让字符串相等 I

题目描述

给你两个长度相等的字符串 s1 和 s2。

你可以任意次 交换 s1 中 下标同为奇数 或 下标同为偶数 的字符。

判断能否通过若干次这样的交换,使得 s1 变成 s2。

示例 1:

输入:s1 = "abcd", s2 = "cdab"

输出:true

解释:交换下标 0 和 2 得到 "cbad",再交换下标 1 和 3 得到 "cdab"。
示例 2:

输入:s1 = "abcd", s2 = "acbd"

输出:false

解释:奇数位字符集合不同。

算法思路

关键观察:

  • 只能交换 奇数下标 之间的字符,或者 偶数下标 之间的字符。
  • 因此,奇数位上的字符 永远无法跑到偶数位上,反之亦然。
  • 问题转化为:
    • s1 中所有奇数下标上的字符组成(频次)必须与 s2 中所有奇数下标上的字符组成完全相同。
    • s1 中所有偶数下标上的字符组成(频次)必须与 s2 中所有偶数下标上的字符组成完全相同。

具体做法

  1. 创建两个二维数组 cnt1[2][26] 和 cnt2[2][26]。
    • 第一维 0 表示偶数下标,1 表示奇数下标。
    • 第二维记录对应位置上每个字母出现的次数。
  2. 遍历字符串,根据下标奇偶性,分别统计 s1 和 s2 中每个字母的频次。
  3. 比较两个统计数组是否完全一致。若一致则返回 true,否则 false。

代码实现(C++)

cpp 复制代码
class Solution {
public:
    bool canBeEqual(string s1, string s2) {
        int cnt1[2][26]{};   // 统计 s1 中奇偶位置的字母频次
        int cnt2[2][26]{};   // 统计 s2 中奇偶位置的字母频次

        for (int i = 0; i < s1.length(); i++) {
            cnt1[i % 2][s1[i] - 'a']++;
            cnt2[i % 2][s2[i] - 'a']++;
        }

        // 内存比较两个统计数组是否相等
        return memcmp(cnt1, cnt2, sizeof(cnt1)) == 0;
    }
};

复杂度分析

  • 时间复杂度 :O(n)
    一次遍历字符串,n 为字符串长度。
  • 空间复杂度 :O(1)
    只使用了固定大小的数组 2×26,与输入规模无关。

正确性证明

  • 必要性:若 s1 能通过合法交换变成 s2,则奇数位集合与偶数位集合分别保持不变,因此频次统计必然相同。
  • 充分性:若奇偶位上的字符频次分别相同,则我们可以在奇数位内任意排列(通过相邻交换实现任意排列),偶数位同理,因此总能构造出 s2。

总结

本题的关键在于将交换限制转化为奇偶位置的独立性,从而用简单的计数比较代替复杂的搜索。这种"奇偶位分离"的思想在字符串处理问题中非常实用。

相关推荐
edtoplort2 小时前
OpenAI紧急叫停GPT-6.1 Astra训练,奥尔特曼为何踩刹车
人工智能·gpt·算法
蒜香可达鸭2 小时前
让视频生成流水线跑不崩:一个事件溯源的多 Agent 可靠执行框架
算法
小羊没烦恼!2 小时前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#
Nebula_g3 小时前
JavaSE拓展:Arrays和Collections工具类
java·开发语言·算法·排序算法·工具类·javase·技术栈
菜鸟~noob2333 小时前
【电子战】 第22篇:误差椭圆与置信区间【含matlab代码】
开发语言·算法·matlab
weixin_307779133 小时前
C++代码实现MATLAB中的normalize函数功能
开发语言·c++·算法·matlab
不会就选b3 小时前
算法日常・每日刷题--<动态规划>11
算法
(Charon)3 小时前
【C++面试】手写String类:同时实现拷贝构造与移动构造
c++·算法
迷途之人不知返3 小时前
算法系列6:模拟
算法
旺仔仔仔4 小时前
# 机器人项目实战(1):选相机、试深度,再到手眼标定
算法