js-practice/src/array/count-the-repetitions.js

150 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 判断从 s2 中删除某些字符是否可以变为 s1
* @param {string} s1
* @param {string} s2
* @return {number} 返回可以变为s1的次数
*/
export const includesInStr = (s1, s2) => {
let i = 0
while (s1.length >= s2.length) {
for (let n = 0, len = s2.length; n < len; n++) {
const tmp = s1.indexOf(s2[n])
if (tmp === -1) {
return i
} else {
s1 = s1.substr(tmp + s2[n].length, s1.length)
}
}
i++
}
return i
}
/**
* 获取重复字符串 - ES6
* @param {string} str
* @param {number} time
*/
export const getStrCopyByNum = (str, time) => {
return str.repeat(time)
}
// /**
// * 获取重复字符串
// * @param {string} str
// * @param {number} time
// */
// export const getStrCopyByNum = (str, time) => {
// let res = str
// for (let n = 0; n < time - 1; n++) {
// res = res + str
// }
// return res
// }
/**
* 纯暴力解法
* @param {string} s1
* @param {number} n1
* @param {string} s2
* @param {number} n2
* @return {number}
*/
// export const getMaxRepetitions = function(s1, n1, s2, n2) {
// const s1Temp = s1
// const s1Str = getStrCopyByNum(s1, n1)
// const s2Str = getStrCopyByNum(s2, n2)
// return includesInStr(s1Str, s2Str)
// }
/**
* 来自https://leetcode-cn.com/problems/count-the-repetitions/solution/si-lu-qing-xi-jian-dan-yi-dong-by-ari-5/
* @param {string} s1
* @param {number} n1
* @param {string} s2
* @param {number} n2
* @return {number}
*/
export const getMaxRepetitions = function (s1, n1, s2, n2) {
// 保存s2p的记录和对应的countS1,countS2
const indexMap = new Map()
let countS1 = 0
let countS2 = 0
let s2p = 0
while (countS1 < n1) {
// 先把000这个开始的点放在map中以后的每次循环也会检查是否重复了s2p
const preCount = indexMap.get(s2p)
if (preCount === undefined) { // 没有就记录
indexMap.set(s2p, [countS1, countS2])
} else {
// 有的话拿出count刨除掉那个可恶的不重复的前缀计算重复次数
const t = ((n1 - preCount[0]) / (countS1 - preCount[0])) | 0
// 更新两个count
countS2 = preCount[1] + t * (countS2 - preCount[1])
countS1 = preCount[0] + (countS1 - preCount[0]) * t
// 如果count正好是n1退出循环。如果还有还要继续走下去
// 为了避免重复读取map和计算计算完重复就把map清除掉来一手过河拆桥
indexMap.clear()
if (countS1 === n1) { break }
}
for (let i = 0; i < s1.length; i++) {
if (s1[i] === s2[s2p]) {
s2p++
if (s2p === s2.length) {
s2p = 0
countS2++
}
}
}
countS1++
}
// 取整
return countS2 / n2 | 0
}
// /**
// * 贪心算法
// * @param {string} s1
// * @param {number} n1
// * @param {string} s2
// * @param {number} n2
// * @return {number}
// */
// // ['aaa',10]和['aa',2]
// // 如果我们找到了2个aaa能表示'3个aa,
// // 那么一共10个的话就可以表示15个aa
// // 那么这个题目的返回值应该就是 15/2 取整其中2是aa的个数
// export const getMaxRepetitions = function(s1, n1, s2, n2) {
// const s1Temp = s1
// const s2Str = getStrCopyByNum(s2, n2)
// let s1Count = 1
// let maxTime = 0
// let maxLength = 0
// for (let n = 0; n < n1; n++) {
// const time = includesInStr(s1, s2Str)
// if (time > 0) {
// console.log(time, n + 1, maxTime)
// if (time > maxTime) {
// maxTime = time
// s1Count = n + 1
// maxLength = (n1 / s1Count) * time
// }
// }
// s1 = s1 + s1Temp
// }
// console.log(maxLength, s1Count)
// return maxLength / s1Count
// }