我无法想出这个问题必须存在的高效算法:
遍历数组检查“标记”元素。如果我发现任何标记没有将其余元素划分为相同长度的运行,请设置一个标志。除了最后一轮,其余部分。
不应设置标志的示例:
*....*....*..*
应设置标志的示例:
*....*...*...*
*....*....**
Intuition说,应该可以在网上做一些非常简单的事情,这可能相当于一些众所周知的问题,而这个问题的名字我不知道。
答案 0 :(得分:1)
<强>解决方案:强>
计算标记之间的元素数量并形成列表。然后检查这个列表元素是否全部相同,不包括最后一个元素,列表的最后一个元素不是0. 边缘情况:只有一个元素,它可以是0.
Python代码:
def is_correct(string):
splitted_list = string.split("*")[1:-1] # Split and strip edge elements.
if len(splitted_list) == 1:
return True
if len(splitted_list[-1]) == 0: # Check that last element is 0.
return False
for i in range(1, len(splitted_list)-1): # Check that others are the same.
if len(splitted_list[0]) != len(splitted_list[i]):
return False
return True
# Test
print is_correct("*....*....*..*")
print is_correct("*....*...*...*")
print is_correct("*....*....**")
答案 1 :(得分:1)
诀窍是首先根据第一次*xyz*
次发生计算预期长度。一旦知道了这一点,我们知道剩下的分隔符(*
)的位置。如果遇到分隔符不合适,除非它是剩余部分的一部分,否则它是非法的。
它与Riko的答案基本上是相同的逻辑,但是由于计算段大小是通过内联而不是使用string.split完成的,所以代码更多。
以下是JavaScript中的示例。我试图通过远离JavaScript的更多功能方面来尽可能简单地保持它。不幸的是,这使它成为一堵代码墙。
var isCorrect = function( str, divider ) {
process.stdout.write( str + ': ' );
// First check the obvious cases. These allow us to skip these checks
// within the loop.
if( str[0] !== divider )
return "Doesn't start with divider";
if( str[ str.length - 1 ] !== divider )
return "Doesnt' end with divider";
// Two variables to hold the state.
// The second variable (divisions) is required only if we want to make
// sure that the last segment is "optimal".
var division = null;
var divisions = 0;
// First find the first divider.
var i = 1;
for( ; i < str.length; i++ ) {
if( str[i] === divider ) {
division = i;
divisions++;
break;
}
}
// Now that we know the division length, make sure the dividers
// are in expected positions.
for( ; i < str.length; i++ ) {
var expectedDivider = ( (i) % division === 0 );
// See if we are expecting a divider.
if( expectedDivider ) {
if( str[i] !== divider )
return "Expected divider at position " + i;
divisions++;
continue;
}
// Since we are not expecting a divider, make sure we don't have one.
if( str[i] === divider ) {
// We had a divider in an unexpected place. This is only allowed for
// the last segment.
if( i < str.length - 1 )
return "Divider not expected at position " + i;
// This is last segment. We could return 'ok' here unless we want
// the optimal segments.
// For optimal segments we want to know whether the last segment
// could have "borrowed" items from the previous ones while still
// remaining smaller than the rest.
// Calculate the bits missing from the last segment.
var offset = ( (i-1) % division );
var missing = division - offset - 1;
if( offset === 0 )
return "Empty division at the end";
// Could the missing bits be taken from the previous divisions?
if( missing > divisions )
return "Last division too short";
// Last segment was OK.
return "ok";
}
}
// All divisions were in expected places:
// Last segment was as long as the rest.
return "ok";
};
我使用的测试用例:
// Simple cases
// OK
console.log( isCorrect( '*--*--*--*', '*' ) );
console.log( isCorrect( '*---*---*---*', '*' ) );
console.log( isCorrect( '*---*---*--*', '*' ) );
// Middle segment too short.
console.log( isCorrect( '*-----*----*-----*', '*' ) );
// First segment too short
console.log( isCorrect( '*----*-----*-----*', '*' ) );
// "Optimality" tests
// In "optimal" division the segments could be divided to three with
// *----*----*---* so *-----*-----*-* is "unoptimal"
console.log( isCorrect( '*-----*-----*-*', '*' ) );
// These are "optimal"
console.log( isCorrect( '*-----*-----*--*', '*' ) );
console.log( isCorrect( '*-----*-----*---*', '*' ) );
console.log( isCorrect( '*-----*-----*----*', '*' ) );
console.log( isCorrect( '*-----*-----*-----*', '*' ) );
// Last segment too long
console.log( isCorrect( '*-----*-----*------*', '*' ) );
// Last segment empty
console.log( isCorrect( '*--*--*--*--*--**', '*' ) );