序文
「安全オファーを証明する」ブラシタイトルノートへの記事のこのシリーズ。
トピック場所:力抑留中国
タイトル
正の整数を入力してtarget
、すべての出力のためのtarget
連続的な正の整数の配列(少なくとも2つの数値を含みます)。
昇順で番号が最初の数字に応じて異なる配列の昇順に配列されています。
例1:
输入:target = 9
输出:[[2,3,4],[4,5]]
例2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
制限事項:
1 <= target <= 10^5
思考
方法、等差数列
なぜなら1の許容誤差演算シーケンスの出力
输入:target = 9
输出:[[2,3,4],[4,5]]
慎重に出力が見やすい守ってください。
- 最初のループは、列2の数を見つけ、徐々にビットの数を増加させるように、各ループの長さは列の数であるので、出力は通常二つ、三つ、四つの構成によって提供される、より多くあります
n
- 各対象の要件の結果は、すべての出力まで追加
target
総和式によって得られた、
算術級数の総和式(首项+末项) * n /2
に変換されます。(a1+(a1+n-1))*n/2
- 合計式は、第一項と最後の項が必要で対応している
a1
と(a1+n-1)
target/n
中央値を得ることができる、a1
及び中央値の距離でありますn/2
したがって、奇数の中央値-n/2
、偶数小さな数の中央値であり、後に自動的にカットを切り捨てn/2
マルチ還元により得られた値1
たとえば、次のtarget
ように9
彼はの長さN 3
のサブ列の数[2,3,4]
、中央値3
、a1
であり2
、a1
中央値はその距離n/2
である3-3/2=2
;彼の長さnは2
サブカラムの数[4,5]
、中央値は4
、a1
です4-2/2+1
。
論理を取得
if n%2 == 1{
a1 := target/n - n/2
}else{
a1 := target/n - n/2 + 1
}
簡素化へ
a1 := target/n - n/2 - (n%2 - 1)
コード
行きます:
func findContinuousSequence(target int) [][]int {
var res [][]int
for n := 2; n < target; n++ {
a1 := target/n - n/2 - (n%2 - 1)
if a1 < 1 {
break
}
if target == (a1+(a1+n-1))*n/2 {
var res_col []int
for i := a1; i < a1+n; i++ {
res_col = append(res_col, i)
}
res = append(res, res_col)
}
}
var revort_res [][]int
for i:=len(res)-1;i>=0;i--{
revort_res = append(revort_res,res[i])
}
return revort_res
}
第二の方法の暴力列挙
从1开始暴力枚举,初始子序列为[1,2]
,求和为3,对比和target
的距离,如果小于就继续增加序列长度为[1,2,3]
直到求和等于target
则把序列加入最终结果集国;如果大于则改变序列起始数字为[2,3]
继续寻找。
js:
var findContinuousSequence = function(target) {
let arr = [];
for (let i = 1; i < target - 1; i++) {
let list = [i, i + 1];
while (add(list) <= target) {
if (add(list) === target) {
arr.push(list);
} else {
list.push(list[list.length - 1] + 1);
}
}
}
console.log(arr);
return arr;
};
function add(arr) {
const reducer = (total, current) => total + current;
return arr.reduce(reducer);
}