每日一题&&学习笔记

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:
  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成
class Solution {
public:
    string longestPalindrome(string s) {
        //获取字符串的长度
        int n=s.size();
        //判断若长度小于2,则直接返回字符串
        if(n<2){
            return s;
        }
        //定义变量存储回文串最大长度和起始位置
        int maxlen=1;
        int begin=0;
        //定义dp存储i到j的子串
        vector<vector<int>> dp(n,vector<int>(n));
        //初始化所有长度为1的子串都是回文串
        for(int i=0;i<n;i++){
            dp[i][i]=true;
        }
        //枚举子串长度
        for(int len=2;len<=n;len++){
            //枚举左边界
            for(int i=0;i<n;i++){
                //定义右边界的下标
                int j=len+i-1;
                //若超出字符串长度,则退出循环
                if(j>=n){
                    break;
                }
                //若左右边界字符不相等,则不为回文串
                if(s[i]!=s[j]){
                    dp[i][j]=false;
                }else{
                    //左边边界相等的情况下且字符串长度小于4,则为回文串
                    if(j-i<3){
                        dp[i][j]=true;
                    }else{          
                        //若左右边界相等且长度大于4,则找该串除左右边界的子串是否为回文串
                        //其实这一行代码是整个动态规划算法的核心
                        //假设我们已知aa为回文串,则为它加上左右边界相等的字母b,也是回文
                        //实际上我们先确定了dp[i+1][j-1]是否为回文串
                        //然后在加上左右相等的边界,即dp[i][j]
                        dp[i][j]=dp[i+1][j-1];
                    }
                }
                //若当前子串为回文串且串长度大于当前最大串长度
                if(dp[i][j]&&j-i+1>maxlen){
                    //则给串最大长度和串起始位置重新赋值
                    maxlen=j-i+1;
                    begin=i;
                }
            }
        }
        //返回找到的最长回文子串
        return s.substr(begin,maxlen);
    }
};

这道题转化为动态规划的思想,找常规字符串中的最长回文子串,就是先固定子串长度,然后左边界从0开始枚举,确定左边界和子串长度后,右边届也可以确定。这样就可以先找到较短的且靠前的回文子串,然后加大子串长度,左边界始终从0开始找。这样其实从长度为2的子串开始,我们已经判断了每一个可能的子串是否为回文串。所以这里动态规划的思想其实是从最小子串长度开始判断每一个子串是否为回文串,然后再加上相同的左右边界,则他是否回文就可以从之前的子串中得出,若他左右不相等,则直接判断为不是回文串。然后再判断一个左右边界和字符串长度即可。

大三学生如果准备考研,制定一个合理的学习计划至关重要。下面是一个建议的大三计算机专业考研学习计划,你可以根据自己的实际情况进行调整: **每天的学习时间分配(假设总时间7-8小时):** 1. **早晨(6:30-8:00):** 早起阅读英语(词汇和阅读理解),或背诵专业课知识点。 2. **上午(8:30-12:00):** 主攻数学或专业基础课程,如数据结构、算法、操作系统等。每门课程分段学习,注重理解和做题。 3. **午休(12:00-13:30):** 合理休息,吃午饭和短暂午睡,为下午保持精力。 4. **下午(13:30-17:00):** 进行专业课复习,如计算机网络、数据库原理等。同时做一些习题巩固。 5. **晚上(17:30-20:00):** 分析历年考研真题,或进行模拟考试。同时注意政治、英语等公共科目的复习。 6. **晚上(20:00-21:30):** 总结一天的学习,整理笔记,回顾重点难点。 7. **晚间(21:30-22:00):** 放松娱乐,比如阅读、运动或听音乐,帮助缓解压力。 **每周的计划(周末留出更多时间进行整体复习和模拟考试):** - 周末:系统复习本周所学内容,做一套完整的模拟试题,并分析错题。 **注意事项:** 1. **保持健康生活**:保证充足的睡眠,均衡饮食,适度运动。 2. **定期测试**:定期进行自我测试,了解进度和薄弱环节。 3. **调整节奏**:根据学习效率灵活调整计划,遇到难题时适当延长学习时间。 4. **保持兴趣**:对考研的热情和兴趣是持久学习的关键。 5. **心理调适**:保持积极心态,学会应对压力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值