当前位置: 首页 > news >正文

算法题 验证外星语词典

953. 验证外星语词典

问题描述

在某种外星语言中,字母表的顺序与英语不同。给定一个字符串数组words和一个表示外星字母表顺序的字符串order,验证这些单词是否按照外星字母表的字典序排列。

字典序规则

  • 比较两个单词时,从左到右逐字符比较
  • 第一个不同的字符决定两个单词的顺序
  • 如果一个单词是另一个单词的前缀,则较短的单词排在前面

示例

输入: words = ["hello","leetcode"], order = "hlabcdefgijkmnopqrstuvwxyz" 输出: true 解释: 'h' 在外星字母表中排在 'l' 前面,所以 "hello" < "leetcode" 输入: words = ["word","world","row"], order = "worldabcefghijkmnpqstuvxyz" 输出: false 解释: "word" 和 "world" 的前缀相同,但 "word" 是 "world" 的前缀,应该排在前面。 但 "row" 应该排在 "world" 前面,因为 'r' < 'w',但实际上 "world" 排在 "row" 前面。 输入: words = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz" 输出: false 解释: "app" 是 "apple" 的前缀,应该排在前面,但实际顺序相反。

算法思路

自定义比较函数

核心思想

  1. 建立字符映射:将外星字母表中的每个字符映射到其在字母表中的位置(0-25)
  2. 逐对比较:遍历相邻的单词对,验证是否按外星字典序排列
  3. 自定义比较:实现一个函数来比较两个单词在外星字母表下的字典序

比较两个单词的规则

  • 从左到右逐字符比较
  • 找到第一个不同的字符,根据外星字母表顺序判断
  • 如果所有对应字符都相同,较短的单词应该排在前面

代码实现

方法一:映射 + 逐对比较

classSolution{/** * 验证外星语词典是否按字典序排列 * * @param words 单词数组 * @param order 外星字母表顺序 * @return 如果单词按外星字典序排列返回true,否则返回false */publicbooleanisAlienSorted(String[]words,Stringorder){// 边界情况处理if(words==null||words.length<=1){returntrue;}// 建立字符到位置的映射int[]charOrder=newint[26];for(inti=0;i<order.length();i++){charOrder[order.charAt(i)-'a']=i;}// 验证相邻单词for(inti=0;i<words.length-1;i++){if(!isLessOrEqual(words[i],words[i+1],charOrder)){returnfalse;}}returntrue;}/** * 比较两个单词是否满足 word1 <= word2(按外星字典序) */privatebooleanisLessOrEqual(Stringword1,Stringword2,int[]charOrder){intlen1=word1.length();intlen2=word2.length();intminLength=Math.min(len1,len2);// 字符比较for(inti=0;i<minLength;i++){charc1=word1.charAt(i);charc2=word2.charAt(i);if(c1!=c2){// 找到第一个不同的字符,比较它们的外星顺序returncharOrder[c1-'a']<charOrder[c2-'a'];}}// 所有对应字符都相同,较短的单词应该排在前面returnlen1<=len2;}}

算法分析

  • 时间复杂度:O©
    • C 是所有单词的字符总数
    • 需要遍历每个字符最多一次
  • 空间复杂度:O(1)
    • 只需要固定大小的映射数组(26个字符)

算法过程

输入:words = ["hello","leetcode"],order = "hlabcdefgijkmnopqrstuvwxyz"

  1. 建立映射
    • 'h' → 0,'l' → 1,'a' → 2,'b' → 3, …
  2. 比较 “hello” 和 “leetcode”
    • 第一个字符:'h'vs'l'
    • 外星顺序:0 < 1
    • 返回true

输入:words = ["apple","app"],order = "abcdefghijklmnopqrstuvwxyz"

  1. 比较 “apple” 和 “app”
    • 前3个字符相同:'a','p','p'
    • “apple” 长度为5,“app” 长度为3
    • 由于没有找到不同字符且5 > 3,返回false

输入:words = ["word","world","row"],order = "worldabcefghijkmnpqstuvxyz"

  1. 建立映射'w'→0, 'o'→1, 'r'→2, 'l'→3, 'd'→4, ...
  2. 比较 “word” 和 “world”
    • 前4个字符相同
    • “word” 长度4 < “world” 长度5
  3. 比较 “world” 和 “row”
    • 第一个字符:'w'vs'r'
    • 外星顺序:0 > 2
    • 返回false

测试用例

publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1:标准示例String[]words1={"hello","leetcode"};Stringorder1="hlabcdefgijkmnopqrstuvwxyz";System.out.println("Test 1: "+solution.isAlienSorted(words1,order1));// true// 测试用例2:前缀问题String[]words2={"apple","app"};Stringorder2="abcdefghijklmnopqrstuvwxyz";System.out.println("Test 2: "+solution.isAlienSorted(words2,order2));// false// 测试用例3:复杂无效序列String[]words3={"word","world","row"};Stringorder3="worldabcefghijkmnpqstuvxyz";System.out.println("Test 3: "+solution.isAlienSorted(words3,order3));// false// 测试用例4:单单词String[]words4={"hello"};System.out.println("Test 4: "+solution.isAlienSorted(words4,order1));// true// 测试用例5:空数组String[]words5={};System.out.println("Test 5: "+solution.isAlienSorted(words5,order1));// true// 测试用例6:两个相同单词String[]words6={"hello","hello"};System.out.println("Test 6: "+solution.isAlienSorted(words6,order1));// true// 测试用例7:正确前缀顺序String[]words7={"app","apple"};System.out.println("Test 7: "+solution.isAlienSorted(words7,order2));// true// 测试用例8:全相同首字母String[]words8={"aa","ab","ac"};Stringorder8="abcdefghijklmnopqrstuvwxyz";System.out.println("Test 8: "+solution.isAlienSorted(words8,order8));// true// 测试用例9:逆序String[]words9={"ac","ab","aa"};System.out.println("Test 9: "+solution.isAlienSorted(words9,order8));// false// 测试用例10:外星字母表完整String[]words10={"kuvp","q"};Stringorder10="ngxlkthsjuoqcpavbfdermiywz";System.out.println("Test 10: "+solution.isAlienSorted(words10,order10));// true// 'k' 在字母表中位置比 'q' 靠前// 测试用例11:长单词String[]words11={"fxasxpc","dfbdrifhp","nwzgs","cmwvwngxry","bj","nwzgs","dfbdrifhp","fxasxpc"};Stringorder11="qwertyuiopasdfghjklzxcvbnm";System.out.println("Test 11: "+solution.isAlienSorted(words11,order11));// false}

关键点

  1. 字符映射

    • 将外星字母表转换为数字索引
    • O(1) 时间复杂度的字符比较
  2. 相邻对验证

    • 字典序具有传递性
    • 只需验证相邻对就能保证全局有序
  3. 前缀处理

    • 当一个单词是另一个的前缀时,较短的应该排在前面
  4. 边界情况

    • 空数组和单元素数组
    • 相同单词的处理
    • 不同长度单词的比较

常见问题

  1. 为什么只需要比较相邻单词?
    • 字典序是传递的:如果 A ≤ B 且 B ≤ C,则 A ≤ C
http://www.jsqmd.com/news/253840/

相关文章:

  • Java毕设选题推荐:基于SpringBoot濒危物种救助信息共享、资源整合调度公益救助交流平台基于SpringBoot濒危物种公益救助交流平台【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 9款免费AI论文生成器实操指南:维普查重一把过不留AIGC痕迹
  • 如何优化销售流程提升效率?关键在于“找对人、说对话、快成交”
  • 《从零学习JMeter》第二篇:JMeter参数化完全指南:从入门到实战避坑
  • ACPI!ACPIBuildDeviceDpc函数分析从ACPIBuildProcessQueueList结束后到处理AcpiBuildRunMethodList
  • 基于django框架和python的的实验室机房预约管理系统的
  • 基于django 的人工智能研讨社区系统
  • 收藏必看!小白入门:一文搞懂LLMs、RAG与AI Agent的区别与应用
  • 斯坦福+伯克利联手解决大模型长上下文难题,TTT-E2E技术详解与谷歌Titans对比,打造个人专属LLM指南
  • 基于django 的学生网上选课系统的设计
  • 数字孪生项目的外包开发流程
  • 基于django山歌文化传播系统
  • 基于django的超市进销存管理系统 供应商
  • 导师推荐!9款AI论文写作软件测评:本科生毕业论文全攻略
  • AI 写论文哪个软件最好?实测虎贲等考 AI:毕业论文的智能通关密钥
  • 全网最全2026本科生AI论文工具TOP10测评
  • 开题报告怎么写?宏智树 AI 手把手教你搞定学术第一步
  • 程序员必学!Claude Skills与MCP协同实战:构建智能代理的收藏级指南
  • 基于djangos线上美食社区论坛交流系统
  • 必学收藏!一张图搞懂RAG、AI Agent和Agentic RAG的区别与联系,程序员小白必备指南
  • 基于django框架和python的的图书借阅及书店图书销售商城管理系统设计与实现
  • 矩阵方程求解
  • 力扣刷题之路
  • 【day 52】神经网络调参指南
  • 收藏级!大模型核心架构与底层原理全解析,小白程序员入门必看
  • 定时任务简单源码思路手撕实现
  • Java swing mysql实现的酒店管理系统_javswing酒店管理系统mysql,零基础入门到精通,收藏这篇就够了
  • Commons-io工具包与Hutool工具包
  • MySQL性能优化:从底层原理到实战落地的全维度方案
  • 【课程设计/毕业设计】基于SpringBoot保护濒危野生动物公益救助交流平台基于SpringBoot濒危物种公益救助交流平台【附源码、数据库、万字文档】