记录 1 道算法题
划分字母区间
要求:根据字母进行划分,划分出的每一段中,每一段里面相同的同一个字母出现最多。同时划分出尽可能多段。将每一段的长度存到数组里返回。
比如:'ababcbacadefegdehijhklij'
输出:[9,7,8]。
注意的是假设还是上面的字符串,第一段是 'ababcbaca'
,假如有字母 a 在更后面的地方,'ababcbacadefagdehijhklij'
,结果就不一样了,所以题目应该是没有这样的设定。
因为可以用贪心的思想,只要得到了每个字母最后出现的位置,那么到这个位置的区域,这个字母都是最多的。但是我们不能保证每一个字母都能够取到他最后出现的位置。贪心的想法就是只要有一个字母取到了他最后出现的位置,那么就进行分段,这一段就是最佳的。
function partitionLabels(s) {
// 存放每个字母最后出现的下标
const z = Array(26)
// 字母和 a 的 code 值相减就是 0 - 25 的下标
const offset = 'a'.charCodeAt(0)
// 第一遍循环获取每个字母最后出现的位置
for(let j = 0; j < s.length; j++) {
// 字母下标位置
const i = s[j].charCodeAt(0) - offset
z[i] = j
}
// 第二次循环进行比较,贪取得最后出现的位置的字母
let start = 0 // 划分的段的开始下标
let end = 0 // 结束下标
const res = []
for(let j = 0; j < s.length; j++) {
const i = s[j].charCodeAt(0) - offset
// 计算结束的位置,但有一点,这也许会被最大的数限制。假如一个字母在一头一尾,那么可能只有一段。
end = Math.max(end, s[i])
// 最后一次出现就是当前下标
if (end === j) {
res.push(end - start + 1) // 长度
start = end + 1
}
}
return res
}