面试题 01.02. 判定是否互为字符重排
01.02. 判定是否互为字符重排 简单
给定两个字符串 s1
和 s2
,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。
示例 1:
输入: s1 = "abc", s2 = "bca"
输出: true
示例 2:
输入: s1 = "abc", s2 = "bad"
输出: false
说明:
0 <= len(s1) <= 100
0 <= len(s2) <= 100
提示:
- 描述两个字符串是否互为字符重排的含义。现在,看看你提供的定义,你能否根据这个定义检查字符串
- 有一种解法需要O(NlogN)的时间。另一种解法需要使用一些.空间,但需要运行时间为O(N)
- 散列表有用吗
- 两个重排的字符串应该具有相同的字符,但顺序不同。你可以让它们的顺序一样吗?
解答
“重新排列后,变成另一个字符串” 根据题干提供的信息,得知
- s1 和 s2 应该长度相同
- s1 和 s2 中出现的字符的数量和类型应该相同
解法一:
自己写的,仅供参考;两次循环,标记符号,没有出现过的直接返回
public bool CheckPermutation(string s1, string s2) {
if(s1.Length!=s2.Length) // 长度不同返回false
return false;
bool isExist; // 标记字符是否在第二个字符串出现过
byte[] flags = new byte[s2.Length]; // 存储s1 在 s2中出现时的标记
foreach(char ch in s1){ // 循环s1中的字符,在s2中出现位置后标记其位置
isExist = false;
for(int i=0;i<s2.Length;i++){
if(ch==s2[i] && flags[i]==0) // 相等时且对应的标记位置为0 时,标记对应位置为 1,跳出当前循环
{
isExist=true;
flags[i] = 1;
break;
}
}
if(!isExist)
return false;
}
return true;
/*
bool[] flags = new bool[s2.Length]; // 存储s1 在 s2中出现时的标记
foreach(char ch in s1){ // 循环s1中的字符,在s2中出现位置后标记其位置
for(int i=0;i<s2.Length;i++){
if(ch==s2[i] && !flags[i]){
flags[i] = true;
break;
}
}
}
foreach(bool isExist in flags){
if(!isExist)
return false;
}
return true;
*/
}
解法2:
来自大家的结合,统计字符数,最后保证所有的字符都是 0
public bool CheckPermutationV2(string s1, string s2)
{
if (s1.Length != s2.Length)
return false;
byte[] flags = new byte[128];
for (int i = 0; i < s1.Length; i++)
{
flags[s1[i]]++;
flags[s2[i]]--;
}
for (int i = 0; i < flags.Length; i++)
{
if (flags[i] != 0)
return false;
}
return true;
}
解法三:
public bool CheckPermutationV3(string s1, string s2)
{
if (s1.Length != s2.Length)
return false;
Dictionary<char, byte> countDict = new Dictionary<char, byte>(s1.Length);
for (int i = 0; i < s1.Length; i++)
{
if (countDict.ContainsKey(s1[i]))
countDict[s1[i]]++;
else
countDict.Add(s1[i], 1);
}
for (int i = 0; i < s2.Length; i++)
{
if (countDict.ContainsKey(s2[i]))
countDict[s2[i]]--;
else
return false;
}
foreach (char curChar in countDict.Keys){
if(countDict[curChar] != 0)
return false;
}
return true;
}
总结
第二种是我目前觉得比较完善的,但是具体的需求还得看具体的分析啦。
C# 类型/关键字 | 范围 | 大小 | .NET 类型 |
---|---|---|---|
sbyte | -128 到 127 | 8 位带符号整数 | System.SByte |
byte | 0 到 255 | 无符号的 8 位整数 | System.Byte |
short | -32,768 到 32,767 | 有符号 16 位整数 | System.Int16 |
ushort | 0 到 65,535 | 无符号 16 位整数 | System.UInt16 |
int | -2,147,483,648 到 2,147,483,647 | 带符号的 32 位整数 | System.Int32 |
uint | 0 到 4,294,967,295 | 无符号的 32 位整数 | System.UInt32 |
long | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 64 位带符号整数 | System.Int64 |
ulong | 0 到 18,446,744,073,709,551,615 | 无符号 64 位整数 | System.UInt64 |
nint | 取决于平台 | 带符号的 32 位或 64 位整数 | System.IntPtr |
nuint | 取决于平台 | 无符号的 32 位或 64 位整数 | System.UIntPtr |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现