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

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

题目描述

给你两个长度相等的字符串 s1s2

你可以任意次 交换 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. 遍历字符串,根据下标奇偶性,分别统计 s1s2 中每个字母的频次。
  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

总结

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

相关推荐
猿人谷21 小时前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络1 天前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络1 天前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao4001 天前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao4001 天前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法
JieE2122 天前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2123 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack204 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树4 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2124 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法