# 第 246 场周赛题解

# Q1 1903. 字符串中的最大奇数 (opens new window)

找到最后一位为奇数的数字,可以直接subStringsubString到该位置,即所求结果。

class Solution {
    fun largestOddNumber(num: String): String {
        for (i in num.indices.reversed()) {
            if ((num[i] - '0') % 2 == 1) {
                return num.substring(0, i + 1)
            }
        }
        return ""
    }
}
1
2
3
4
5
6
7
8
9
10

# Q2 1904. 你完成的完整对局数 (opens new window)

将分钟考向最近的1515的整数倍,注意开始时间和结束时间的靠近方向不同。最后看下时间是否为负值,负数的话需要+上一整天。

class Solution1904 {
    fun numberOfRounds(startTime: String, finishTime: String): Int {
        val (sh, sm) = startTime.split(":").map { it.toInt() }
        val (fh, fm) = finishTime.split(":").map { it.toInt() }
        val s = sh * 60 + sm
        var f = fh * 60 + fm
        if (f < s) {
            f += 60 * 24
        }
        val rf = f / 15 * 15
        return maxOf(0, (rf - s)) / 15
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# Q3 1905. 统计子岛屿 (opens new window)

使用BFSBFS求解,注意每次岛屿2需要划出一整片岛屿一起判断,有任何一块陆地在岛屿1中是海洋,整体岛屿都不能计算到结果中。使用DFSDFS超时.. 改成BFSBFS才过,以后能用BFSBFS都用BFSBFS,不要用DFSDFS

class Solution5791 {
    fun countSubIslands(grid1: Array<IntArray>, grid2: Array<IntArray>): Int {
        // 方向
        val ori = arrayOf(
                intArrayOf(-1, 0),
                intArrayOf(0, -1),
                intArrayOf(0, 1),
                intArrayOf(1, 0)
        )

        fun bfs(i: Int, j: Int): ArrayList<IntArray> {
            val queue: Queue<IntArray> = LinkedList<IntArray>()
            queue.add(intArrayOf(i, j))
            grid2[i][j] = 2
            val ans = ArrayList<IntArray>()
            while (queue.isNotEmpty()) {
                val size = queue.size
                for (k in 0 until size) {
                    val item = queue.poll()
                    ans.add(item)
                    for (o in ori) {
                        val ni = item[0] + o[0]
                        val nj = item[1] + o[1]
                        if (ni in grid2.indices && nj in grid2[0].indices && grid2[ni][nj] == 1) {
                            grid2[ni][nj] = 2
                            queue.offer(intArrayOf(ni, nj))
                        }
                    }
                }
            }
            return ans
        }

        var ans = 0
        for (i in grid2.indices) {
            for (j in grid2[0].indices) {
                if (grid2[i][j] == 1) {
                    val land = bfs(i, j)
                    if (land.all { grid1[it[0]][it[1]] == 1 })
                        ans++
                }
            }
        }
        return ans
    }
}
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

# Q4 1906. 查询差绝对值的最小值 (opens new window)

由于限定了数字的大小只能是1..1001..100,可以以此为切入点。可以利用前缀和,计算出两个点之前的数组段包含的值。遇到这种queryquery的题,我更习惯用线段树来处理,将mergemerge逻辑传入即可。

线段树中的默认值是BooleanArrayBooleanArray,长度100100,默认值falsefalse。合并时就取indexindex的或运算结果。每次queryquery直接求解相应线段树内的值对应的BooleanArrayBooleanArray,然后遍历它内部truetrue值的最小间距即可。

class Solution1906 {
    fun minDifference(nums: IntArray, queries: Array<IntArray>): IntArray {
        val seg = SegmentTree<BooleanArray>(start = 0, end = nums.lastIndex, value = BooleanArray(101)) { a, b ->
            val ans = BooleanArray(101)
            for (i in ans.indices) {
                ans[i] = a[i] or b[i]
            }
            ans
        }
        for (i in nums.indices) {
            val arr = BooleanArray(101)
            arr[nums[i]] = true
            seg.update(seg, i, i, arr)
        }
        val ans = arrayListOf<Int>()
        queries.forEach {
            seg.query(seg, it[0], it[1]).also {
                var lst = -1
                var cur = Int.MAX_VALUE
                for (i in it.indices) {
                    if (!it[i]) continue
                    if (lst == -1) {
                        lst = i
                    } else {
                        cur = minOf(cur, i - lst)
                        lst = i
                    }
                }
                if (cur == Int.MAX_VALUE) ans.add(-1)
                else ans.add(cur)
            }
        }
        return ans.toIntArray()
    }
}
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