一天一大 lee(回文对)难度:困难-Day20200806
时间:2022-07-25
本文章向大家介绍一天一大 lee(回文对)难度:困难-Day20200806,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:[1]
给定一组唯一的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
示例
- 示例 1
输入: ["abcd","dcba","lls","s","sssll"]
输出: [[0,1],[1,0],[3,2],[2,4]]
解释: 可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]
- 示例 2
输入: ["bat","tab","cat"]
输出: [[0,1],[1,0]]
解释: 可拼接成的回文串为 ["battab","tabbat"]
抛砖引玉
抛砖引玉
暴力解法
- 任取 words 中的字符与其他字符拼接验证是否为回文字符
- 注意使用左右边界验证回文时,单个字符也属于回文字符
/**
* @param {string[]} words
* @return {number[][]}
*/
var palindromePairs = function (words) {
let i = 0,
_result = []
while (i < words.length) {
let j = 1
while (j < words.length && i !== j) {
if (check(words[i], words[j])) _result.push([i, j])
if (check(words[j], words[i])) _result.push([j, i])
j++
}
i++
}
// 检验是否为回味字符
function check(a, b) {
if (a.length + b.length === 1) return true
let str = a + b,
left = 0,
right = str.length - 1
while (left < right) {
if (str.charAt(left) === str.charAt(right)) {
left++
right--
} else {
// 对位不相同则返回false
return false
}
}
return true
}
return _result
}
枚举前缀和后缀
- 组成回文的可能情况
- a 为 b 到倒序,a+b 刚好组成回文字符
- a 或 b 自身存在回文片段,剩余的判断和另外的字符拼接形成完成的回文字符
- 那么将所有字符划分成前缀后缀组成的字符,验证片段是否为回文,为回文则去查找是否有满足条件的另一半
- 注意:当截取的前缀后缀判断为 0 时,默认为回文字符,则是情况 1,全文平均的回文字符查找
/**
* @param {string[]} words
* @return {number[][]}
*/
var palindromePairs = function (words) {
let n = words.length,
_result = [],
map = new Map()
for (let i = 0; i < n; ++i) {
// 生成倒序字符字符map
const str = words[i].split('').reverse().join('')
map.set(str, i)
}
for (let i = 0; i < n; i++) {
let word = words[i],
m = words[i].length
if (m == 0) continue
for (let j = 0; j <= m; j++) {
// 前缀片段为回文,则验证后缀片段是否存在与之匹配的回文
if (check(word, j, m - 1)) {
let leftId = findWord(word, 0, j - 1)
if (leftId !== -1 && leftId !== i) {
_result.push([i, leftId])
}
}
// 同理,后缀片段为回文,则验证前缀片段是否可以匹配到回文
if (j !== 0 && check(word, 0, j - 1)) {
let rightId = findWord(word, j, m - 1)
if (rightId !== -1 && rightId !== i) {
_result.push([rightId, i])
}
}
}
}
function check(s, left, right) {
let len = right - left + 1
for (let i = 0; i < len / 2; i++) {
if (s.charAt(left + i) !== s.charAt(right - i)) {
return false
}
}
return true
}
function findWord(s, left, right) {
return map.has(s.substring(left, right + 1))
? map.get(s.substring(left, right + 1))
: -1
}
return _result
}
参考资料
[1]
题目:: https://leetcode-cn.com/problems/palindrome-pair
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring 一个接口多个实现类怎么注入
- ASP.NET MVC Controller的激活
- js 逗号表达式
- spring动态调用方法
- Spring AOP动态代理原理与实现方式
- 基于注解多数据源解决方案
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
- 你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它?
- java阻塞队列得实现
- 谈谈如何利用 valgrind 排查内存错误
- 用java写一个死锁
- Runnable和Thread比较
- 使用@ConditionalOnProperty注解
- Java注解Annotation与自定义注解详解
- spring boot 配置多个DispatcherServlet