【数据结构与算法】leetcode刷题记录(最长回文串+z型变换)

最长回文字串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

python解决:

1.暴力法:

(思路没啥好说的 , 超时是个问题)

def force(self, s: str) -> str:  
        if s==s[::-1]:
            return s
        max_len = 1
        res = s[0]
        for i in range(len(s) - 1):
            for j in range(i + 1, len(s)):
                if j - i + 1 > max_len and s[i:j+1] == s[i:j+1][::-1]:
                    max_len = j - i + 1
                    res = s[i:j + 1]
        return res

2.中心扩散:

​ (奇数回文串)以当前位置为圆心 ,

​ 向两边对比,如果相同,那继续,

​ 如果不相同, 返回当前位置的最长字串

然后奇数的情况下,对字符串的每个位置都进行一遍操作,

偶数的情况下,对字符串每个位置进行操作:

不同的是,偶数回文串是 i 和 i+1 对比 , 但奇数的字符串是 以中心为圆心,两边对比

class Solution:
    def longestPalindrome(self, s: str) -> str:
        res = ""
        for i in range(len(s)): 
            temp = self.findSubString(s, i, i) 
            if len(temp) > len(res):
                res = temp 
            temp = self.findSubString(s, i, i + 1) 
            if len(temp) > len(res):
                res = temp
        return res
    def findSubString(self,s, l, r):
        while l >= 0 and r < len(s) and s[l] == s[r]:
            l -= 1
            r += 1
        return s[l + 1:r] 

java解法:

1中心扩散:(使用StringBuffer来进行操作)

(奇数回文串)以当前位置为圆心 ,

​ 向两边对比,如果相同,那继续,

​ 如果不相同, 返回当前位置的最长字串

然后奇数的情况下,对字符串的每个位置都进行一遍操作,

偶数的情况下,对字符串每个位置进行操作:

不同的是,偶数回文串是 i 和 i+1 对比 , 但奇数的字符串是 以中心为圆心,两边对比

class Solution {
    public String longestPalindrome(String s) {
        StringBuffer res = new StringBuffer("");
        for(int i = 0;i<s.length();i++){
            StringBuffer s3 = getSubstring(s,i,i);
            if(s3.length()>res.length()){
                res.delete(0,res.length());
                res.append(s3);
            }
            StringBuffer s4 = getSubstring(s,i,i+1);
            if(s4.length()>res.length()){
                res.delete(0,res.length());
                res.append(s4);
            }
        }
        return res.toString();
    }
    public StringBuffer getSubstring(String s,int l,int r){
        StringBuffer s2 = new StringBuffer("");
        char[] s1 = s.toCharArray();
        while (l>=0 && r < s1.length && s1[l]==s1[r]){
            l--;
            r++;
        }
        for(int i = 0;i<s1.length;i++){
            if(i>=l+1 && i <r){
                s2.append(s1[i]);
            }
        }
        return s2;
    }
}

z型变换:

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

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

L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
解释:

L   C   I   R
E T O E S I I G
E   D   H   N

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

python解决:

按思路来讲:

假设 字符串是 : abcdefg n = 3

那么 , 将 生成 三行 字符串

""
""
""

a–>第一行 b–> 第二行 c -->第三行 d–>第二行 e–>第一行

不难发现插入顺序为 1–2--3–2--1–2--3–2--1–2--3–2--1

所以只需要遍历字符串,更改替换的行即可:

class Solution:
    def convert(self, s: str, num: int) -> str:
        if num < 2: 
            return s
        res = ["" for _ in range(num)]
        i, flag = 0, -1
        for c in s:
            res[i] += c
            if i == 0 or i == num - 1: 
                flag = -flag
            i += flag
        return "".join(res)

java解决:

1.插入顺序为 1–2--3–2--1–2--3–2--1–2--3–2--1

所以只需要遍历字符串,更改替换的行即可:

class Solution {
    public String convert(String s, int num) {
        if(num < 2){
            return s;
        }
        List<StringBuilder> rows = new ArrayList<StringBuilder>();
        for(int i = 0; i < num; i++) {
            rows.add(new StringBuilder());
        }
        int i = 0, flag = -1;
        for(char c : s.toCharArray()) {
            rows.get(i).append(c);
            if(i == 0 || i == num -1) {
                flag = - flag;
            }
            i += flag;
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder row : rows) {
            res.append(row);
        }
        return res.toString();
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值