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

总结

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

相关推荐
散峰而望1 小时前
【算法练习】算法练习精选:陶陶摘苹果(基础+升级)、Music Notes、字串变换,你能AC几道?
数据结构·c++·算法·leetcode·贪心算法·github·动态规划
暗夜猎手-大魔王1 小时前
转载--Hermes Agent 04 | Agent 主循环:一次对话背后发生了什么
人工智能·python·算法
手写码匠1 小时前
华为云Flexus+DeepSeek征文|基于华为云Flexus X实例 + Dify + DeepSeek 构建企业级智能知识库问答系统实战
人工智能·深度学习·算法·aigc
吴可可1232 小时前
Win7上开发CAD2004自定义实体全解析
c++·算法
YXXY3132 小时前
二叉树中的深搜算法介绍
算法
zz34572981132 小时前
C语言中字符串常量存储位置
c语言·开发语言·算法·青少年编程
noipp2 小时前
推荐题目:洛谷 P16510 [GKS 2015 #C] gRanks
java·c语言·开发语言·c++·python·算法
菜菜的顾清寒2 小时前
力扣HOT100(50)动态规划-零钱兑换
算法·leetcode·动态规划
周末也要写八哥2 小时前
三分钟读懂:如何解决做题数量不足的问题?
算法
8Qi82 小时前
LeetCode 148. 排序链表 —— 解法二:自底向上归并(迭代,O(1) 空间)
数据结构·算法·leetcode·链表·归并·迭代