力扣刷题第三天

5. 最长回文子串

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

示例 1:

输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:

输入:s = “cbbd”
输出:“bb”

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

此问题可拆分为子问题进行求解,且子问题的解包含在问题的解中,因此可采用动态规划。

思路:
回文字符串特征:首字符与尾字符相同,最长回文字符串被去除首尾字符之后仍然是回文字符串,因此自底向上只需考虑首字符是否与尾字符相同。
字符串长度为1时,为回文字符串。
字符串长度为2或3时,若首尾字符串相同,则为回文字符串。
s [ i : j ] s[i:j] s[i:j]表示回文字符串,则 s [ i + 1 : j − 1 ] s[i+1:j-1] s[i+1:j1]也一定是回文字符串.
动态规划方程(写给自己看的。。。不规范): s [ i : j ] = s [ i + 1 : j − 1 ] ( 回文字符串长度大于 3 ) s[i:j] = s[i+1:j-1] (回文字符串长度大于3) s[i:j]=s[i+1:j1](回文字符串长度大于3)

在这里插入图片描述

代码:

class Solution {
public:
    string longestPalindrome(string s) {
        //动态规划
        int length = s.length();//字符串长度

        if(length==1){
            return s;
        }

        int result_set[length][length];//结果集,result_set[i][j]表示字符串第i个位置到第j个位置间的子串是否为回文字符串。0为否,1为是。

        //初始化结果集,当字符串长度为1时,单个字符均为回文子串
        for(int i=0; i < length; i++){
            result_set[i][i] = 1;
        }
        //此时
        int max_len = 1;//最长回文子串长度为1
        int begin_id = 0;//最长回文子串首字母位置可以为任意一个字符的下标,选0

        //字符串长度大于1时
        for(int l=2; l <= length; l++){
            for(int i=0; i < length; i++){
                int j = l + i - 1;//j为尾字符位置,因为l=j-i+1,回文字符串的特性->首字符与尾字符相同,字符长度大于1时,比对首字符与尾字符即可
                if(j >= length){
                    break;
                }
                if(s[i]==s[j]){
                    if(j-i < 3){
                        result_set[i][j] = 1;
                    } else {
                        result_set[i][j] = result_set[i+1][j-1];
                    }
                    
                    //cout << i << " " << j << " " << result_set[i][j] << endl;
                    if(max_len < l && result_set[i][j] == 1){
                        max_len = l;
                        begin_id = i;
                    }
                } else {
                    result_set[i][j] = 0;
                }
            }
        }
        //cout << result_set[1][2] << endl;
        //cout << begin_id << " ";
        //cout << max_len;
        return s.substr(begin_id, max_len);
    }
};

6. Z 字形变换

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

以Z字形排列,第一行第一个字符与第二个字符之间的间隔为 2 ( n u m R o w s − 1 ) 2(numRows-1) 2(numRows1)即排列的周期为2(numRows-1),最后一行处于排列周期的分界线处,到达最后一行的字符之前,排列是从上往下的,而到达最后一行的字符后,排列从下往上。

在这里插入图片描述
代码:

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows==1){
            return s;
        }
        string res_set[numRows];//存放排列结果
        int rId = 0;
        for(int i=0; i < s.length(); i++){
            res_set[rId] += s[i];
            if(i%(2*numRows-2) < numRows-1 ){//判断是否到达最后一行
                rId++;//从上往下排
            } else {
                --rId;//从下往上排
            }
        }

        string result = "";//拼接字符串数组获取最终结果
        for(int i=0; i<numRows; i++){
            result += res_set[i];
        }
        return result;

    }
};

string的字符串截取函数s.substr()

string.substr(size_type _Off = 0,size_type _Count = npos);
//size_type _Off表示从哪一个位置开始
//size_type _Count表示截取的字符串长度
string s = "12345";
s.substr(1,3);//从下标1开始,截取长度为3的字符串,即“234”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值