当前位置: 首页 > 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.cnnetsun.cn/news/652818.html

相关文章:

  • 数字员工是什么?熊猫智汇在现代企业中的应用价值有哪些?
  • 全网最全2026本科生AI论文工具TOP10测评
  • 必学收藏!一张图搞懂RAG、AI Agent和Agentic RAG的区别与联系,程序员小白必备指南
  • 斯坦福+伯克利联手解决大模型长上下文难题,TTT-E2E技术详解与谷歌Titans对比,打造个人专属LLM指南
  • 【day 52】神经网络调参指南
  • JVM 里的逻辑漏洞,居然让你的哈希表慢了 20%!
  • 2022VS及以上版本的scanf函数的使用,引发的错误导致编译器运行不了
  • 【深度】大模型工具平台对比评测:从部署到应用,一篇搞定所有知识点(建议收藏)
  • 【收藏级干货】RAG技术深度解析:让大语言模型告别“闭卷考试“
  • 2026 AI市场分析榜单:原圈科技领跑,不懂将错失增长先机
  • SpringBoot + Vue 实现 Python 在线调试器 - 技术方案文档
  • 基于 Flutter × HarmonyOS 6.0 开发的文本净化工具 ——「TextCleaner」
  • 企业内部在线学习培训系统
  • SSL/TLS 协议详解:安全通信的基石
  • DNS服务协议有哪些?
  • 基于物联网的室内大棚监测系统的设计与实现
  • AI赋能的11项论文写作解决方案,涵盖LaTeX排版与智能改写功能
  • 导师严选2026自考AI论文网站TOP10:高效写作全维度测评
  • 收藏级指南:Agentic RAG 彻底升级传统RAG,打造能干活的AI数字同事
  • 【计算化学与人工智能驱动的 MOFs 性能预测与筛选技术】
  • listmap数据变驼峰
  • 【Java毕设全套源码+文档】基于springboot的可追溯果蔬生产过程的管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 拒稿退散!宏智树 AI 解锁期刊论文录用密码
  • 查重 + AIGC 双险通关!宏智树 AI:给论文注入人工原创灵魂
  • 【Java毕设源码分享】基于springboot+vue的水果在线销售系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 【Java毕设源码分享】基于springboot+vue的二手书交易商城系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 全球抗量子迁移战略白皮书(2025)
  • 如何应对AI生成重复内容:精选十大工具评测及有效解决策略
  • 公信会议:AI 会议生态服务商,解锁数智协作新可能
  • 谁还以为网安只会挖洞就行?2025 卷王标准:云原生 + AI 攻防,速来聊聊你的技能升级计划!