leecode刷题

本文主要探讨了LeetCode中的两道经典算法题:最长回文子串和最长公共子序列。对于最长回文子串,介绍了中心扩散法的解决方案,通过遍历字符串并检查回文串长度来找到最长回文子串。而对于最长公共子序列问题,提出了动态规划的解题思路,利用二维数组记录子序列长度,通过比较字符是否相等来更新状态并找到最长公共子序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 最长回文子串

最长公共子序列

5. 最长回文子串

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

示例 1:

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

示例 2:

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

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"

该题有多种方法1.暴力解法  2,。中心扩散法   3.动态规划

选择中心扩散法:

首先一个字符串的长度可能为奇数也可能为偶数,所以写的代码要同时满足这两种情况,所以在这道题中使用for循环遍历字符串,把s.charAt(i)作为中心,来看回文字符串长度为多少,接着返回回文串的长度。然后求出奇数和偶数回文串长度的最大值,如果该最大值大于之前的最大值就更新回文串即将要返回的结果。

代码:

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()==0||s==null){
            return "";
        }
        int start=0,end=0;
        for(int i=0;i<s.length();i++){
            int len1=lenHW(s,i,i);
            int len2=lenHW(s,i,i+1);
            int maxlen=Math.max(len1,len2);
            if(maxlen>end-start){
                start=i-(maxlen-1)/2;
                end=i+maxlen/2;
            }
            

        }

 return  s.substring(start,end+1);
    }
    public  int lenHW(String s,int left,int right){
        while(left>=0 && right<s.length() && s.charAt(left)==s.charAt(right)){
            left--;
            right++;
        }
        return  right-left-1;//长度应该是right-left-2+1;
    }
}

1143. 最长公共子序列

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

  • 例如,"ace""abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace" ,它的长度为 3 。

示例 2:

输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc" ,它的长度为 3 。

示例 3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0 。

 思路:动态规划,定义一个二维数组,

假设字符串 text1和 text2的长度分别为 m和 n,创建 m+1 行n+1 列的二维数组 dp,其中 dp[i][j],dp[i][j] 表示 text1[0:i]和 text2[0:j] 的最长公共子序列的长度。首先是dp[i][0]和dp[0][j]为0,因为空字符和任何比最长公共子序列都为0,

当 text1[i - 1] == text2[j - 1] 时,说明两个子字符串的最后一位相等,所以最长公共子序列又增加了 1,所以 dp[i][j] = dp[i - 1][j - 1] + 1;举个例子,比如对于 ac 和 bc 而言,他们的最长公共子序列的长度等于 a 和 b 的最长公共子序列长度 0 + 1 = 1。
当 text1[i - 1] != text2[j - 1] 时,说明两个子字符串的最后一位不相等,那么此时的状态 dp[i][j] 应该是 dp[i - 1][j] 和 dp[i][j - 1] 的最大值。举个例子,比如对于 ace 和 bc 而言,他们的最长公共子序列的长度等于 ① ace 和 b 的最长公共子序列长度0 与 ② ac 和 bc 的最长公共子序列长度1 的最大值,即 1

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
      int len1=text1.length();
      int len2=text2.length();
      int [][]dp=new int[len1+1][len2+1];
      for(int i=1;i<=len1;i++){
          char c1=text1.charAt(i-1);
          for(int j=1;j<=len2;j++){
              char c2=text2.charAt(j-1);
              if(c1==c2){
                  dp[i][j]=dp[i-1][j-1]+1;
              }else{
                  dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
              }

          }
         
      }
 return  dp[len1][len2];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值