# 第 272 场周赛题解
# Q1 2108. 找出数组中的第一个回文字符串 (opens new window)
签到。
class SolutionA {
fun firstPalindrome(words: Array<String>): String {
return words.firstOrNull { it == it.reversed() } ?: ""
}
}
1
2
3
4
5
2
3
4
5
# Q2 2109. 向字符串添加空格 (opens new window)
继续签到。(这以往也就是简单题)
class SolutionB {
fun addSpaces(s: String, spaces: IntArray): String {
val sb = StringBuilder(s)
var offset = 0
spaces.forEach {
sb.insert(it + offset, ' ')
offset++
}
return sb.toString()
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Q3 2110. 股票平滑下跌阶段的数目 (opens new window)
仍然签到。每次增加以当前为结尾的子数组数目。
class SolutionC {
fun getDescentPeriods(prices: IntArray): Long {
var ans = 0L
var cur = 1L
for (i in prices.indices) {
if (i != 0 && prices[i] == prices[i - 1] - 1) {
cur++
} else {
cur = 1L
}
ans += cur
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Q4 2111. 使数组 K 递增的最少操作次数 (opens new window)
最长非递减子序列。增加是否严格递增的变量,扩展方法快速支持(这里等号少写一个,WA了一次...)。
class SolutionD {
fun kIncreasing(arr: IntArray, k: Int): Int {
val l = Array<ArrayList<Int>>(k) { ArrayList<Int>() }
for (i in arr.indices) {
l[i % k].add(arr[i])
}
var ans = 0
for (i in 0 until k) {
ans += l[i].size - l[i].toIntArray().lis(false)
}
return ans
}
}
/**
* 单调递增子序列长度
*
* @param strict 是否严格递增 true 严格递增 false 可以相等
* */
fun IntArray.lis(strict: Boolean = true): Int {
var len = 1
val n: Int = this.size
if (n == 0) {
return 0
}
val d = IntArray(n + 1)
d[len] = this[0]
for (i in 1 until n) {
if (this[i] > d[len] || (!strict && this[i] == d[len])) {
d[++len] = this[i]
} else {
var l = 1
var r = len
var pos = 0
while (l <= r) {
val mid = l + r shr 1
if (d[mid] < this[i] || (!strict && d[mid] == this[i])) {
pos = mid
l = mid + 1
} else {
r = mid - 1
}
}
d[pos + 1] = this[i]
}
}
return len
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48