经典算法面试题目-判断两个字符串是否是变位词(1.4)

简介: 题目Write a method to decide if two strings are anagrams or not.写一个函数判断两个字符串是否是变位词。解答变位词(anagrams)指的是组成两个单词的字符相同,但位置不同的单词。

题目

Write a method to decide if two strings are anagrams or not.

写一个函数判断两个字符串是否是变位词。

解答

变位词(anagrams)指的是组成两个单词的字符相同,但位置不同的单词。

比如说, abbcd和abcdb就是一对变位词。
也就是说,2个字符串,不管排列顺序如何,只要全部的单个字符能对应上,就是一对变位词!

该题目有两种做法:

时间复杂度为O(nlogn)的解法

由于组成变位词的字符是一模一样的,所以按照字典序排序后,两个字符串也就相等了。 因此我们可以用O(nlogn)的时间去排序,然后用O(n)的时间比较它们是否相等即可。

代码如下:

//需要头文件#include<algorithm>

bool isAnagram1(string s, string t){
    if(s=="" || t=="") return false;
    if(s.length() != t.length()) return false;

    //sort(s,s+s.length);//如果s是字符数组,就这样调用
    sort(&s[0], &s[0]+s.length());
    sort(&t[0], &t[0]+t.length());
    if(s == t) return true;
    else return false;
}

时间复杂度为O(n)的解法

由于组成变位词的字符是一模一样的, 因此我们可以先统计每个字符串中各个字符出现的次数, 然后看这两个字符串中各字符出现次数是否一样。如果是,则它们是一对变位词。 这需要开一个辅助数组来保存各字符的出现次数。我们可以开一个大小是256的整数数组(ascii码范围内的字符), 遍历第一个字符串时,将相应字符出现的次数加1;遍历第二个字符串时, 将相应字符出现的次数减1。最后如果数组中256个数都为0,说明两个字符串是一对变位词。 (第1个字符串中出现的字符都被第2个字符串出现的字符抵消了), 如果数组中有一个不为0,说明它们不是一对变位词。

代码如下:

//必须有头文件:#include <cstring>

bool isAnagram2(string s, string t){
    if(s=="" || t=="") return false;
    if(s.length() != t.length()) return false;

    int len = s.length();
    int c[256];
    memset(c, 0, sizeof(c));
    for(int i=0; i<len; ++i){
        ++c[(int)s[i]];
        --c[(int)t[i]];
    }

    for(int i=0; i<256; ++i)
        if(c[i] != 0)
            return false;
    return true;
}

全部代码:

#include <iostream>
#include <algorithm>//用sort函数必须加的头文件
#include <cstring>
using namespace std;

bool isAnagram1(string s, string t){
    if(s=="" || t=="") return false;
    if(s.length() != t.length()) return false;

    //sort(s,s+s.length);//如果s是字符数组,就这样调用
    sort(&s[0], &s[0]+s.length());
    sort(&t[0], &t[0]+t.length());
    if(s == t) return true;
    else return false;
}

bool isAnagram2(string s, string t){
    if(s=="" || t=="") return false;
    if(s.length() != t.length()) return false;

    int len = s.length();
    int c[256];
    memset(c, 0, sizeof(c));
    for(int i=0; i<len; ++i){
        ++c[(int)s[i]];
        --c[(int)t[i]];
    }

    for(int i=0; i<256; ++i)
        if(c[i] != 0)
            return false;
    return true;
}

int main()
{
    string s="asdfghj";
    string t="jhgfdsa";
    bool bo = isAnagram1(s,t);
    cout<<bo<<endl;//输出结果为1

    s="asdfghj";
    t="jhgfdss";
    bo = isAnagram1(s,t);
    cout<<bo<<endl;//输出结果为0

    s="asdfghj";
    t="jhgfdsa";
    bo = isAnagram2(s,t);
    cout<<bo<<endl;//输出结果为1

    s="asdfghj";
    t="jhgfdss";
    bo = isAnagram2(s,t);
    cout<<bo<<endl;//输出结果为0
    return 0;
}
目录
相关文章
|
3月前
|
存储 算法
算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
给定一个正整数数组和目标值target,找出总和大于等于target的最短连续子数组长度。利用滑动窗口(双指针)优化,维护窗口内元素和,通过单调性避免重复枚举,时间复杂度O(n)。当窗口和满足条件时收缩左边界,更新最小长度,最终返回结果。
|
7月前
|
Web App开发 缓存 前端开发
浏览器常见面试题目及详细答案解析
本文围绕浏览器常见面试题及答案展开,深入解析浏览器组成、内核、渲染机制与缓存等核心知识点。内容涵盖浏览器的主要组成部分(如用户界面、呈现引擎、JavaScript解释器等)、主流浏览器内核及其特点、从输入URL到页面呈现的全过程,以及CSS加载对渲染的影响等。结合实际应用场景,帮助读者全面掌握浏览器工作原理,为前端开发和面试提供扎实的知识储备。
321 4
|
3月前
|
存储 算法 编译器
算法入门:剑指offer改编题目:查找总价格为目标值的两个商品
给定递增数组和目标值target,找出两数之和等于target的两个数字。利用双指针法,left从头、right从尾向中间逼近,根据和与target的大小关系调整指针,时间复杂度O(n),空间复杂度O(1)。找不到时返回{-1,-1}。
|
7月前
|
缓存 NoSQL Java
Java Redis 面试题集锦 常见高频面试题目及解析
本文总结了Redis在Java中的核心面试题,包括数据类型操作、单线程高性能原理、键过期策略及分布式锁实现等关键内容。通过Jedis代码示例展示了String、List等数据类型的操作方法,讲解了惰性删除和定期删除相结合的过期策略,并提供了Spring Boot配置Redis过期时间的方案。文章还探讨了缓存穿透、雪崩等问题解决方案,以及基于Redis的分布式锁实现,帮助开发者全面掌握Redis在Java应用中的实践要点。
417 6
|
7月前
|
算法 Java 关系型数据库
校招 Java 面试基础题目解析及学习指南含新技术实操要点
本指南聚焦校招Java面试,涵盖Java 8+新特性、多线程与并发、集合与泛型改进及实操项目。内容包括Lambda表达式、Stream API、Optional类、CompletableFuture异步编程、ReentrantLock与Condition、局部变量类型推断(var)、文本块、模块化系统等。通过在线书店系统项目,实践Java核心技术,如书籍管理、用户管理和订单管理,结合Lambda、Stream、CompletableFuture等特性。附带资源链接,助你掌握最新技术,应对面试挑战。
179 2
|
7月前
|
安全 Java 编译器
Java 校招面试题目合集及答案 120 道详解
这份资料汇总了120道Java校招面试题目及其详细答案,涵盖Java基础、JVM原理、多线程、数据类型、方法重载与覆盖等多个核心知识点。通过实例代码解析,帮助求职者深入理解Java编程精髓,为校招面试做好充分准备。无论是初学者还是进阶开发者,都能从中受益,提升技术实力和面试成功率。附带的资源链接提供了更多学习材料,助力高效备考。
384 3
|
7月前
|
存储 算法 Java
校招 java 面试基础题目及解析
本文围绕Java校招面试基础题目展开,涵盖平台无关性、面向对象特性(封装、继承、多态)、数据类型、关键字(static、final)、方法相关(重载与覆盖)、流程控制语句、数组与集合、异常处理等核心知识点。通过概念阐述和代码示例,帮助求职者深入理解并掌握Java基础知识,为校招面试做好充分准备。文末还提供了专项练习建议及资源链接,助力提升实战能力。
180 0
|
10月前
|
算法
面试场景题:如何设计一个抢红包随机算法
本文详细解析了抢红包随机算法的设计与实现,涵盖三种解法:随机分配法、二倍均值法和线段切割法。随机分配法通过逐次随机分配金额确保总额不变,但易导致两极分化;二倍均值法优化了金额分布,使每次抢到的金额更均衡;线段切割法则将总金额视为线段,通过随机切割点生成子金额,手气最佳金额可能更高。代码示例清晰,结果对比直观,为面试中类似算法题提供了全面思路。
1620 16
|
12月前
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
489 16
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)