今天在JavaScript技术采访中有人问我这个问题,但我失败了,但仍然找不到解决方案。我想出的问题和解决方案如下。我通过了一些测试用例,但是代码仍然不能在每种情况下都起作用。如果有人可以帮助我有效地解决问题,我将不胜感激。
系统会为您提供一个字符串输入,由大小写不同的字母组成。
这些字母应根据大小写彼此配对。例如,字母“ N”与字母“ a”按此顺序形成“匹配对”。
规则:
输出:您的方法应返回最后一个匹配的小写字母的从零开始的索引;如果不存在对,则返回-1。
限制:0 < input length < 10,000
个字符最佳方法的运行时间为O(输入长度)。
样本输入#1
ABba
样品输出#1
3
这是我所做的,但是它不适用于每个测试用例;
function stringMatch(str){
let word=str.split("")
let lastIndex;
if (word[0]===word[0].toUpperCase()){
for(let i=0;i<word.length;i++){
if(word[i]===word[i].toUpperCase()){
if(word[i].toLowerCase()===word[i+1] || word[i+1]===word[i+1].toUpperCase() ){
lastIndex=i
}
else{
return -1
}
}
else{
lastIndex=i
}
}
return lastIndex
}
}
答案 0 :(得分:1)
一个很好的方法是使用一个包含大写字母的堆栈。堆栈的下一个元素应始终是您要匹配的下一个小写字母。
遍历字符串,对于每个字母(如果大写),将其压入堆栈并继续。如果是小写字母,则从堆栈中弹出一个并进行比较。如果匹配,则将索引设置为最后匹配的索引,然后继续操作;如果不匹配,则返回最后匹配的索引。
const isUpper = (l) => l === l.toUpperCase()
function findUnmatchedIndex(str) {
let stack = []
let lastMatch = -1
for (let i = 0; i < str.length; i++) {
let letter = str[i]
if (isUpper(letter)) {
stack.push(letter);
continue;
}
let next = stack.pop()
if (next !== letter.toUpperCase()) return lastMatch
lastMatch = i
}
return lastMatch
}
console.log(findUnmatchedIndex('ABba'))
console.log(findUnmatchedIndex('ABCcDEedFeGHi'))
console.log(findUnmatchedIndex('ABCbDEedFeGHi'))
答案 1 :(得分:0)
没有更多的测试用例,对此我不确定。但这看起来可能符合要求。
const isLower = (c) => 'a' <= c && c <= 'z'
const final = (stack) => stack[stack.length - 1]
const initial = (stack) => stack.slice(0, stack.length - 1)
const check = (str) => str.split('').reduce(
({lastIndex, failed, stack}, c, idx) =>
failed
? {lastIndex, failed, stack} // one reason not to do this with reduce.
: isLower(c)
? c === final(stack)
? {lastIndex: idx, failed, stack: initial(stack)}
: {lastIndex, failed: true, stack}
: {lastIndex, failed, stack: stack.concat(c.toLowerCase())},
{lastIndex: -1, failed: false, stack: []}
).lastIndex
console.log(check('ABba'))