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

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


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

题目描述

小红拿到一个只包含 '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的典型应用(打家劫舍模型)。

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

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

相关推荐
witAI4 小时前
**AI仿真人剧技术解析2025,专业评估与适配指南**
人工智能·python
程序设计实验室4 小时前
现代 Python 程序优雅处理日期时间的避坑指南
python
心疼你的一切4 小时前
【矛与盾的博弈:ZLibrary反爬机制实战分析与绕过技术全解析】
人工智能·爬虫·python·网络爬虫
老前端的功夫4 小时前
【Java从入门到入土】21:List三剑客:ArrayList、LinkedList、Vector的爱恨情仇
java·javascript·网络·python·list
吃一根烤肠4 小时前
Trae Builder模式实战:10分钟生成可部署的Flask电商项目
python·flask·建造者模式
samson_www4 小时前
用nssm部署FASTAPI服务
数据库·python·fastapi
小李云雾4 小时前
零基础-从ESS6基础到前后端联通实战
前端·python·okhttp·中间件·eclipse·html·fastapi
axinawang4 小时前
XPath与lxml解析库
爬虫·python
电商API&Tina5 小时前
唯品会数据采集API接口||电商API数据采集
java·javascript·数据库·python·sql·json