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

总结

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

相关推荐
ZhangShao06072 分钟前
题解:CF2249B
c++·算法
小玮看世界2 分钟前
[Python]线段树与二分法
数据结构·算法
Tisfy3 小时前
LeetCode 3345.最小可整除数位乘积 I:暴力枚举(从n开始尝试)
数学·算法·leetcode·题解·枚举
DolphinDB智臾科技3 小时前
告别 TB 级数据搬运:DolphinDB 滤波算法库,重塑物联网数据价值链
物联网·算法
可编程芯片开发4 小时前
基于双PI控制器结构的六步逆变器供电无刷直流电机调速simulink仿真
算法
Sagittarius_A*4 小时前
后量子密码|通识认知 02|量子威胁核心原理:Shor 算法如何击穿传统公钥密码
算法·信息安全·密码学·量子计算
青山木4 小时前
Hot 100 --- 在排序数组中查找元素的第一个和最后一个位置
java·数据结构·算法·leetcode
其美杰布-富贵-李4 小时前
聚类算法详解:K-means、层次聚类与 DBSCAN
算法·机器学习·kmeans·聚类
碧海银沙音频科技研究院5 小时前
4 BES2710编译环境搭建方法
嵌入式硬件·算法
mifengxing5 小时前
LeetCode 238 除自身以外数组的乘积|无除法O(n)时间+O(1)空间双解法
java·算法·leetcode