LeetCode 每日一题 2026/10/19-2026/10/25

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步


目录

      • [10/19 2089. 找出数组排序后的目标下标](#10/19 2089. 找出数组排序后的目标下标)
      • [10/20 3886. 可排序整数求和](#10/20 3886. 可排序整数求和)
      • [10/21 3863. 将一个字符串排序的最小操作次数](#10/21 3863. 将一个字符串排序的最小操作次数)
      • [10/22 3942. 排序排列的最少操作数](#10/22 3942. 排序排列的最少操作数)
      • [10/23 3644. 排序排列](#10/23 3644. 排序排列)
      • [10/24 2409. 统计共同度过的日子数](#10/24 2409. 统计共同度过的日子数)
      • [10/25 1254. 统计封闭岛屿的数目](#10/25 1254. 统计封闭岛屿的数目)

10/19 2089. 找出数组排序后的目标下标

遍历一次 nums,统计 target 出现的次数 count,以及小于 target 的数的个数 small。

排序后 target 的位置从 small 开始,一共持续 count 个。

python 复制代码
def targetIndices(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: List[int]
    """
    small = 0
    count = 0
    for num in nums:
        if num==target:
            count+=1
        elif num<target:
            small+=1
    ans = [small+i for i in range(count)]
    return ans

10/20 3886. 可排序整数求和

k 必须整除数组长度。把数组切成若干段长度为 k 的连续子数组,每段只能整体旋转,转完后整个数组要变成非递减。

一段能转成非递减,当且仅当把它首尾连成一个圈,变小的地方最多只有一处。

从左往右看每一段:左边已经能排好的那些数里的最大值,不能大于从这里开始一直到末尾的最小值,否则拼起来还会下降。

先预处理前缀最大值、后缀最小值和相邻下降次数,每个因数 k 就能直接判断。把所有可行的 k 加起来。

python 复制代码
def sortableIntegers(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n = len(nums)
    pref_max = [0] * (n + 1)
    for i, x in enumerate(nums):
        pref_max[i + 1] = max(pref_max[i], x)
    suff_min = [10**9] * (n + 1)
    for i in range(n - 1, -1, -1):
        suff_min[i] = min(nums[i], suff_min[i + 1])
    pref_drop = [0] * n
    for i in range(1, n):
        pref_drop[i] = pref_drop[i - 1] + (nums[i - 1] > nums[i])

    def ok(k):
        for start in range(0, n, k):
            end = start + k - 1
            drops = pref_drop[end] - pref_drop[start]
            if nums[end] > nums[start]:
                drops += 1
            if drops > 1 or pref_max[start] > suff_min[start]:
                return False
        return True

    ans = 0
    for k in range(1, n + 1):
        if n % k == 0 and ok(k):
            ans += k
    return ans

10/21 3863. 将一个字符串排序的最小操作次数

每次只能把一段真子串排成非降序,不能一次排整个字符串。

已经排好就不用操作。只有两个字符又没排好时,任何真子串都改变不了它们的顺序,返回 -1。

开头已经是最小字母,把后面整段排一次即可;结尾已经是最大字母,把前面整段排一次即可。

否则最小或最大字母出现在中间,先排一段把它送到开头或结尾,再把剩下那段排好。

最小字母只在结尾、最大字母只在开头时,要三次才能排好。

python 复制代码
def minOperations(s):
    """
    :type s: str
    :rtype: int
    """
    n = len(s)
    if all(s[i] <= s[i + 1] for i in range(n - 1)):
        return 0
    if n == 2:
        return -1
    mn, mx = min(s), max(s)
    if s[0] == mn or s[-1] == mx:
        return 1
    if any(c == mn or c == mx for c in s[1:-1]):
        return 2
    return 3

10/22 3942. 排序排列的最少操作数

只能整体反转,或者把第一个数挪到末尾。这两种操作改不了数字在圆环上的相对顺序,只会换方向、换起点。

所以从 0 出发,顺着或逆着走一圈,必须正好是 0,1,2,...,n-1,否则排不出来。

顺着递增时,左旋 zero 次就能把 0 转到开头;也可以先反转、再转、再反转回来,次数是 n-zero+2。

逆着递增时,先转到再反转要 zero+2 次,先反转再转到要 n-zero 次。

两种方向里取最小的次数,都不行就返回 -1。

python 复制代码
def minOperations(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n = len(nums)
    zero = nums.index(0)

    def check(step):
        for i in range(1, n):
            prev = (zero + (i - 1) * step) % n
            curr = (zero + i * step) % n
            if nums[prev] > nums[curr]:
                return False
        return True

    ans = n + 3
    if check(1):
        ans = min(ans, zero, n - zero + 2)
    if check(-1):
        ans = min(ans, zero + 2, n - zero)
    return -1 if ans == n + 3 else ans

10/23 3644. 排序排列

只有不在自己位置上的数才需要交换。两个数能交换,当且仅当它们的按位与正好等于 k,所以 k 里每一个是 1 的位,这些错位数里也必须是 1。

因此最大的 k 就是所有错位数的按位与。这个 k 自己也在数组里,可以拿它当中转,把错位数换到该去的位置。

数组已经有序就不用交换,返回 0。

python 复制代码
def sortPermutation(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    ans = -1
    for i, x in enumerate(nums):
        if i != x:
            ans &= x
    return max(ans, 0)

10/24 2409. 统计共同度过的日子数

同一年里,把日期转化成该年第几天。

两人共同在的日子,是到达日里较晚的那天到离开日里较早的那天。到达比对方离开还晚,就没有交集,返回 0。

python 复制代码
def countDaysTogether(arriveAlice, leaveAlice, arriveBob, leaveBob):
    """
    :type arriveAlice: str
    :type leaveAlice: str
    :type arriveBob: str
    :type leaveBob: str
    :rtype: int
    """
    mon = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    d = [0]*12
    for i in range(1,12):
        d[i] = d[i-1]+mon[i-1]
    
    def trans(date):
        m = int(date[:2])
        ind = d[m-1]
        ind += int(date[-2:])
        return ind
    aA = trans(arriveAlice)
    aB = trans(arriveBob)
    lA = trans(leaveAlice)
    lB = trans(leaveBob)
    if aA>lB or aB>lA:
        return 0
    return min(lA,lB)-max(aA,aB)+1

10/25 1254. 统计封闭岛屿的数目

0 是陆地,1 是水。上下左右连在一起的陆地算一座岛,碰到网格边界的岛不算封闭。

先从四条边上的陆地出发,把和边界连在一起的整片陆地都改成水。

然后再看内部还剩下的陆地,每找到一片就计数,并把它整片改成水,避免重复统计。

python 复制代码
def closedIsland(grid):
    """
    :type grid: List[List[int]]
    :rtype: int
    """
    m, n = len(grid), len(grid[0])

    def flood(x, y):
        st = [(x, y)]
        while st:
            i, j = st.pop()
            if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 1:
                continue
            grid[i][j] = 1
            st.append((i + 1, j))
            st.append((i - 1, j))
            st.append((i, j + 1))
            st.append((i, j - 1))

    for i in range(m):
        flood(i, 0)
        flood(i, n - 1)
    for j in range(n):
        flood(0, j)
        flood(m - 1, j)
    ans = 0
    for i in range(1, m - 1):
        for j in range(1, n - 1):
            if grid[i][j] == 0:
                ans += 1
                flood(i, j)
    return ans

相关推荐
Rain的Java大神之路2 小时前
面了 50 个候选人,90% 都挂在 LeetCode 3 无重复字符的最长子串:滑动窗口的 5 个致命坑
java·后端·leetcode
ZhengEnCi2 小时前
一亿条数据取前100条完全指南:从全量排序到分块流式最小堆的4种解法实测
python·算法·排序算法
zaizai10072 小时前
STL深度剖析2
java·c++·算法
数智奔流3 小时前
MiniMax的低价攻势,撞上“背题”疑云
前端·javascript·算法
青少儿编程课堂3 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:位运算实战——二进制权限与最大异或解析
c++·python·算法·bfs·信息学竞赛
广州智造3 小时前
Radioss中破坏模型FAILTAB1的详细介绍
数据库·人工智能·算法·机器学习·仿真软件·radioss
青少儿编程课堂3 小时前
2026蓝桥杯青少组图形化真题:校园飞机大战解析(全国青少年信息素养·电子学会图形化考级)
c++·python·算法·bfs·信息学竞赛
开开心心就好3 小时前
证件照排版打印工具,免费可自定义尺寸
服务器·开发语言·算法·随机森林·pdf·音视频·散列表
lisw053 小时前
导数与机器学习优化!
算法·机器学习·数学建模