T5 最长回文串

case1:使用dp思想
dp[start][end] 表示字符串s的[start,end]区间是否为回文串
状态转移方程:

   dp[start][end] = curLen==1||(curLen==2||dp[start+1][end-1])&&s.charAt(start)==s.charAt(end)

怎么理解这个状态转移方程: 长度为1的串或者长度为2且首尾相同的串或者符合中心扩延的串均为回文串
时间复杂度为O(n ^ 2),空间复杂度O(n^2)

class Solution {
    public String longestPalindrome(String s) {  
      int len = s.length();
      if(len<=1)return s;
      boolean[][]dp = new boolean[len][len];
      int finalLeft = 0,finalRight = 0,maxLen = 0;
      //穷举串s的所有长度的子串
      for(int curLen=1;curLen<=len;curLen++){
          for(int start=0;start<len;start++){
              int end = start+curLen-1;
              if(end>=len) continue;
              //判断其是否为回文串
              dp[start][end] = (curLen==1)||(curLen==2||dp[start+1][end-1])&&s.charAt(start)==s.charAt(end);
              if(dp[start][end]){
                 if(end-start+1>maxLen){
                     maxLen = (end-start+1);
                     finalLeft = start;
                     finalRight = end;
                 }  
              }
          }
      }
      return s.substring(finalLeft,finalRight+1); 
    }
}

case2:使用中心扩延定理,长度为n的串中心有2n+1个
时间复杂度为O(n^2),空间复杂度为O(1)

class Solution {
    public String longestPalindrome(String s) {  
      int len = s.length();
      if(len<=1)return s;
      int centerCounts = 2*len + 1;
      int finalLeft = 0,finalRight = 0;//分别指向最终找到最长回文子串的左端点和右端点
      for(int cid=0;cid<centerCounts;cid++){
          int left = (cid / 2) ,right = left + (cid % 2);
          while(left>=0&&right<len&&s.charAt(left)==s.charAt(right)){
             left--;
             right++;
          }
          if((right-left-1)>(finalRight-finalLeft+1)){
              finalLeft = left+1;
              finalRight = right-1;
          }
      }
      return s.substring(finalLeft,finalRight+1);
    }
}

上面两种方法都会找出当前字符串s的所有回文子串,所以它们还可以用来求字符串s的回文子串总数或者找出所有的回文子串

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个MIPS汇编程序,用于检查输入的字符串是否为回文串: ``` .data prompt: .asciiz "Enter string: " # 提示用户输入字符串 output: .asciiz "The string is a palindrome." # 字符串为回文串的输出消息 not_palindrome: .asciiz "The string is not a palindrome." # 字符串不为回文串的输出消息 str: .space 80 # 用于存储输入的字符串,最大长度为 80 .text .globl main main: # 输出提示消息 li $v0, 4 la $a0, prompt syscall # 读入字符串 li $v0, 8 la $a0, str li $a1, 80 syscall # 计算字符串长度 move $t0, $a0 # 将字符串首地址保存到 $t0 中 li $t1, 0 # 计数器清零 loop: lb $t2, ($t0) # 读取一个字符 beqz $t2, check_palindrome # 如果读到了字符串结尾,跳转到检查回文串的代码 addi $t0, $t0, 1 # 字符串指针加 1 addi $t1, $t1, 1 # 计数器加 1 j loop check_palindrome: subi $t0, $t0, 1 # 将字符串指针指向最后一个字符 li $t2, 0 # 初始化计数器 div $t1, 2 # 计算字符串长度的一半 mflo $t3 # 将商保存到 $t3 中 loop2: lb $t4, ($a0) # 读取一个字符 lb $t5, ($t0) # 从字符串末尾读取一个字符 bne $t4, $t5, not_palindrome # 如果两个字符不相等,跳转到输出不是回文串的代码 addi $a0, $a0, 1 # 字符串指针加 1 subi $t0, $t0, 1 # 从字符串末尾往前移动一个字符 addi $t2, $t2, 1 # 计数器加 1 bne $t2, $t3, loop2 # 如果还没有遍历完整个字符串,跳转到 loop2 # 如果程序能够执行到这里,说明字符串是回文串 li $v0, 4 la $a0, output syscall j end not_palindrome: li $v0, 4 la $a0, not_palindrome syscall end: li $v0, 10 syscall ``` 该程序首先提示用户输入字符串,然后读取字符串。程序接着计算字符串长度,并将字符串指针移动到最后一个字符的位置。然后,程序使用循环比较字符串的首尾字符是否相等,如果相等,则将指针向后移动一个字符,向前移动一个字符,直到遍历整个字符串或者发现首尾字符不相等。如果整个字符串都被遍历了,并且字符串中的所有字符都相等,则说明该字符串是回文串,程序输出相应的消息。如果发现首尾字符不相等,则说明该字符串不是回文串,程序输出相应的消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值