算法题解合集:回文子串、不相邻取数、空调遥控

在算法学习和刷题过程中,我们会遇到各种有趣的题目,今天就来分享三道不同类型题目的解法思路,分别是回文子串最短长度不相邻取数最大和空调遥控最佳温度区间


一、回文子串最短长度(小红的字符串)

题目描述

小红拿到一个只包含 'a''b''c'三种字符的字符串。她想知道,这个字符串最短的、长度超过1的回文子串的长度是多少?

  • 子串定义:字符串中取一段连续 的区间(例如 "abcca"的子串有 "ab""bcca"等,但 "aca"不是子串)。

  • 回文定义:正着读和倒着读都相同的字符串(例如 "aa""aba")。

  • 若不存在长度超过1的回文子串,输出 -1

解题思路

由于字符串只包含 'a''b''c'三种字符,最短的回文子串长度只能是 2 或 3

  • 长度为 2 的回文子串:两个相同字符(如 "aa""bb""cc")。

  • 长度为 3 的回文子串:首尾字符相同(如 "aba""bcb")。

因此,我们只需要枚举所有二元组(长度2的子串)三元组(长度3的子串),判断是否为回文,找到最短的那个即可。

代码实现(Python)

复制代码
def shortest_palindrome(s):
    n = len(s)
    # 先检查所有长度为2的子串
    for i in range(n - 1):
        if s[i] == s[i + 1]:
            return 2
    # 再检查所有长度为3的子串
    for i in range(n - 2):
        if s[i] == s[i + 2]:
            return 3
    # 没有符合条件的回文子串
    return -1

# 测试示例
print(shortest_palindrome("abcca"))  # 输出2("cc"是回文)
print(shortest_palindrome("abcab"))  # 输出-1(无长度>1的回文)

二、不相邻取数(动态规划 - 线性DP)

题目描述

小红拿到一个数组,想取一些不相邻的数,使得取出的数之和尽可能大。请帮助她求出这个最大和。

  • 输入:第一行是正整数 n(数组长度),第二行是 n个正整数 a_i

  • 输出:不相邻数的最大和。

解题思路

这是经典的**"打家劫舍"型动态规划问题** 。设 dp[i]表示前 i个元素中,不相邻取数的最大和。

状态转移方程:

  • 对于第 i个元素(i >= 2),有两种选择:

    • 不选第 i个元素:dp[i] = dp[i-1](继承前 i-1个的最大和)。

    • 选第 i个元素:dp[i] = dp[i-2] + a[i](前 i-2个的最大和 + 第 i个元素)。

  • 因此,dp[i] = max(dp[i-1], dp[i-2] + a[i])

边界条件:

  • dp[0] = a[0](只有一个数时,最大和是它本身)。

  • dp[1] = max(a[0], a[1])(两个数时,选较大的那个)。

代码实现(Python)

复制代码
def max_non_adjacent_sum(nums):
    n = len(nums)
    if n == 0:
        return 0
    if n == 1:
        return nums[0]
    # 初始化dp数组
    dp = [0] * n
    dp[0] = nums[0]
    dp[1] = max(nums[0], nums[1])
    for i in range(2, n):
        dp[i] = max(dp[i-1], dp[i-2] + nums[i])
    return dp[-1]

# 测试示例
nums = [2, 6, 4, 1]
print(max_non_adjacent_sum(nums))  # 输出7(选6和1)

三、空调遥控(二分 / 滑动窗口)

题目描述

集训室有 n名队员,每位队员的温度诉求为 a[i]。当室内温度为 K时,若 |a[i] - K| ≤ p,队员能正常训练;否则会躁动。求最佳情况下,最多能有多少队员同时进入训练状态

解题思路

方法一:滑动窗口(排序后)
  1. 排序 :将温度诉求数组 a排序,方便后续窗口操作。

  2. 滑动窗口 :维护一个窗口 [left, right],使得窗口内的**最大值 - 最小值 ≤ 2p *(因为 |a[i]-K| ≤ p等价于 K ∈ [a[i]-p, a[i]+p],所以窗口内所有数必须在同一个长度为 2*p的区间内)。

  3. 统计最大窗口大小:窗口越大,满足条件的队员越多。

方法二:二分查找
  1. 排序:同样先对数组排序。

  2. 二分枚举答案 :假设最多能满足 k名队员,判断是否存在一个长度为 k的连续子数组,其最大值 - 最小值 ≤ 2*p。

  3. 验证函数 :对于每个可能的 k,用二分法找是否存在这样的子数组。

代码实现(Python - 滑动窗口)

复制代码
def max_trainers(a, p):
    a.sort()
    n = len(a)
    left = 0
    max_len = 0
    for right in range(n):
        # 收缩左边界,直到窗口内最大值-最小值 ≤ 2*p
        while a[right] - a[left] > 2 * p:
            left += 1
        # 更新最大窗口长度
        max_len = max(max_len, right - left + 1)
    return max_len

# 测试示例
n, p = 6, 2
a = [1, 5, 3, 2, 4, 6]
print(max_trainers(a, p))  # 输出5(温度调为3或4时,5人满足)

总结

这三道题分别覆盖了字符串处理动态规划滑动窗口/二分查找三种经典算法思路:

  • 回文子串:利用字符种类少的特性,枚举短子串。

  • 不相邻取数:线性DP的典型应用(打家劫舍模型)。

  • 空调遥控:排序后用滑动窗口或二分查找优化区间问题。

通过这类题目练习,可以加深对算法思路的理解,提升代码实现能力~ 🚀

相关推荐
兵慌码乱3 小时前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot5 小时前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海9 小时前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱12 小时前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
曲幽17 小时前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
荣码17 小时前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
兵慌码乱1 天前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
金銀銅鐵1 天前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学
FreakStudio1 天前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
用户0332126663671 天前
使用 Python 从零创建 Word 文档
python