最长回文子串(Longest Palindromic substring)

news2025/1/11 5:57:07

什么叫回文串

就是正读和反读都是一样的字符串,比如aba,abba,cdc像这样的字符串都是回文字符串

 暴力破解法来查找最长的回文子串

这个图解的意思就是我们要拿到每一个右边的数,然后与左边的数一一匹配

下面看一下java的实现代码

package com.pxx;

/**
 * Created by Administrator on 2023/9/11.
 */
public class Test2 {

    public static String longestPalindrome(String s) {
        if (s == null) {
            return null;
        }

        //从最右边才是最长的,越往里面走,越短
        for (int len = s.length(); len >= 1; len--) {
            //这里i + len是保证你每一个回文串的长度来整体字符串长度之内
            for (int start = 0; start + len <= s.length(); start++) {
                if (isPalindrome(s,start,start + len - 1)) {
                    return s.substring(start,start + len);
                }
            }
        }
        //没有结果就返回空串
        return "";
    }

    //直接判断是否是回文数
    private static boolean isPalindrome(String s,int left,int right) {
        while (left < right && s.charAt(left) == s.charAt(right)) {
            left++;
            right--;
        }
        //如果是回文数的情况下,肯定会造成left >= right的,某种情况来说,left == right程序就已经截止了
        return left >= right;//为真就是回文串,为假就不是回文串
    }

    public static void main(String[] args) {
        String res = longestPalindrome("abcdzdcab");
        System.out.println(res);
    }
}

下面是c语言代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 判断是否是回文字符串
bool isPalindrome(const char* s, int left, int right) {
    while (left < right && s[left] == s[right]) {
        left++;
        right--;
    }
    return left >= right;
}

// 查找最长回文子串
const char* longestPalindrome(const char* s) {
    if (s == NULL) {
        return NULL;
    }
    for(int len = strlen(s); len >= 1; len--) {
        for(int start = 0; start + len <= strlen(s); start++) {
            if(isPalindrome(s,start,start + len - 1)) {
                char* result = (char*)malloc(sizeof(char) * (start + len));
                strncpy(result, s + start, start + len - 2);
                result[start + len] = '\0';
                return result;
            }
        }
    } 

    return "";
}

int main() {
    const char* input = "abcdzdcab";
    const char* result = longestPalindrome(input);

    printf("Input: %s\n", input);
    printf("Longest palindrome: %s\n", result);

    free((void*)result); // 释放动态分配的内存

    return 0;
}

上面这个算法的时间复杂度是O(n^3) 

 

基于中心点的枚举法Enumeration来实现查找最长子串

实现原理

 

上面是大体实现,具体要分奇数回文串来看或者偶数回文串来看 

 奇数部分代码实现原理分析

 偶数部分代码实现原理分析

 下面是java代码实现

public class Enumeration {

	//主体函数
	//拿到字符串里面的最长回文字符串
	public static String longestPolindrom(String s) {
		//安全性检查
		if(s == null) {
			return null;
		}
		//定义一个我们需要返回的字符串
		String longest = "";
		//遍历整个字符串然后检查
		for(int i = 0; i < s.length(); i++) {
			//这里是奇数部分的查找
			String oddPolindrome = getPolindromeFrom(s,i,i);//之前分析过,奇数其实就是固定一点,左右散发,这里是i
			//判定一下是否把得到的回文串给替换不
			if (longest.length() < oddPolindrome.length()) {//小于返回的就替换,因为我们要找最长的
				longest = oddPolindrome;//直接把这个字符串给替换
			}
			//这里是偶数串的查找
			String evenPolindrome = getPolindromeFrom(s,i,i+1);//偶数串就不能固定一个点
			if (longest.length() < evenPolindrome.length()) {
				longest = evenPolindrome;
			}
		}
		
		//上面循环完之后返回
		return longest;
		
	}

	//得到回文字符串
	public static String getPolindromeFrom(String s, int left, int right) {
		//双指针,相向而行的一个双指针
		while (left >= 0 && right < s.length()) {
			if (s.charAt(left) != s.charAt(right)) {
				break;//先break掉
			}
			left--;
			right++;
			
		}
		//最后直接截断
		//这个截断是包头不包尾
		//left这个位置已经是不相等的位置了
		return s.substring(left + 1,right);
	}	

	public static void main(String[] args) {
		String res = longestPolindrom("abcdzdcab");
		System.out.println(res);
	}
}

运行结果:

 下面是c++代码实现

#include <cstdio>
#include <string>
#include <algorithm>


using namespace std;

//写一个函数返回回文字符串的长度
int expand_around_center(const string& s,int left,int right) 
{
	int len = s.length();
	while (left >= 0 && right < len && s[left] == s[right]) {
		left--;//往左边扩展
		right++;//往右边扩展
	}
	//一旦上面不满足了,就返回这个长度
	return right - left -1; 
}

//主函数:查找最长的回文子串
string longest_palindrome(const string& s) 
{
	int start = 0, end = 0;//初始化最长回文子串的起始位置与结束位置

	int len = s.length();
	for (int i = 0; i < len; i++) {
		//开始轮替,这里分为奇数轮替与偶数的轮替
		int len1 = expand_around_center(s,i,i);
		int len2 = expand_around_center(s,i,i + 1);

		//上面都会返回文子串的长度,也有可能返回0,我们就取其中最大的就行了
		int max_len = max(len1,len2);//依赖头文件<algorithm>

		//如果当前返回的长度 > 之前记录的长度
		//需要更新起始位置与结束位置
		//这段代码直接背下来
		if (max_len > end - start) {
			start = i - (max_len - 1) / 2;
			end = i + max_len / 2;
		}
	}

	//上面整体循环完了之后,start与end都是边界,然后用substr截取
	return s.substr(start,end - start + 1);//为什么加1,因为end -start就会少一个数 2 4 =》 4 - 2 + 1
}

int main() 
{
	string input = "abcdzdcab";
	string result = longest_palindrome(input);
	printf("input : %s\n",input.c_str());
	//这是c++的方法,可以理解为把string->char*,然后让printf进行打印
	printf("Longest palindrom: %s\n",result.c_str());
	return 0;
}

运行结果:

下面用图解的方式对c++的部分进行分析

 解析1:right  - left - 1

解析2:

 

有几个小的知识点我得说一下:

第一个:关于-1/2=0,本来应该是-0.5,但是1与2都是整型嘛,然后后面就截断了 0不占符号位,如果还是-4/2 = -2,这个时候就得有符号位

第二个:printf()不能打印char*的c语言类型的字符串,所以字符串可以调用c_str()函数变成包含了c语言指针的字符串

那如果我们用c语言处理呢,就把上面代码修改一下就可以了下面看代码

#include <cstdio>
#include <cstdlib>
#include <cstring>

// 辅助函数:查找以left和right为中心的最长回文子串
int expandAroundCenter(char *s, int left, int right) {
    int len = strlen(s);
    while (left >= 0 && right < len && s[left] == s[right]) {
        left--;
        right++;
    }
    return right - left - 1;//这里返回回文串的长度
}

// 主函数:查找最长回文子串
char *longestPalindrome(char *s) {
    int start = 0; // 最长回文子串的起始位置
    int end = 0;   // 最长回文子串的结束位置

    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        // 以每个字符为中心,分奇数和偶数长度回文子串两种情况进行扩展
        int len1 = expandAroundCenter(s, i, i);
        int len2 = expandAroundCenter(s, i, i + 1);

        // 取两种情况中的较长者
        int maxLen = len1 > len2 ? len1 : len2;

        // 如果当前回文子串的长度大于之前记录的最长回文子串长度
        // 则更新起始和结束位置
        if (maxLen > end - start) {
            start = i - (maxLen - 1) / 2;
            end = i + maxLen / 2;
        }
    }

    // 根据起始和结束位置截取最长回文子串
    char *result = (char*)malloc(sizeof(char) * (end - start + 2));
    strncpy(result, s + start, end - start + 1);
    result[end - start + 1] = '\0';

    return result;
}

int main() {
    char input[] = "babad";
    char *result = longestPalindrome(input);

    printf("Input: %s\n", input);
    printf("Longest Palindrome: %s\n", result);

    free(result); // 释放分配的内存

    return 0;
}

下面是对一部分核心代码的讲解

 这个算法的时间复杂度是O(n^2)

先说到这

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/999407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详细解析如何用“双指针“解题(面试必备,小白一看就会系类)

一、前言 大家在平时的训练和交流中肯定多少都会听过或者见过用"双指针"去快速的解题&#xff0c;那么大家有没有想过&#xff0c;为什么要用"双指针"呢&#xff1f;这里的"双指针"和我们平时了解的指针一样吗&#xff1f; 其实&#xff0c;这里…

Python数据分析实战-表连接-merge四种连接方式用法(附源码和实现效果)

实现功能 表连接-merge四种连接方式用法&#xff0c; 将两个pandas表根据一个或者多个键&#xff08;列&#xff09;值进行连接。 实现代码 import pandas as pddf1 pd.DataFrame({key: [a, b, d],data1: range(3)}) print(df1)df2 pd.DataFrame({key: [a, b, c, a, b],dat…

电商商品的前后台类目设计思路,小本本记下来(提供获取京东淘宝商品类目信息API 免费测试)

今天&#xff0c;我们来聊聊商品类目的设计思路。 商品是电商的根基&#xff0c;核心目标是销&#xff0c;也就是卖货。卖货可以多层理解&#xff0c;卖给谁&#xff0c;怎么卖&#xff0c;什么货&#xff0c;其实就是人货场的概念。 我理解的货&#xff0c;不仅是商品层面&a…

使用python requests上传文件

import requests# 指定要上传的文件 files {file: (example.txt, open(1.py, rb))}# 发送POST请求上传文件 response requests.post(http://baidu.com, filesfiles, proxies{http: 127.0.0.1:8080})# 检查响应 if response.status_code 200:print(文件上传成功) else:print(…

连续相同idx 性能为4cycle、不同idx性能为2cycle

mem_bypass结合Tdm 技术&#xff08;通信技术知识积累&#xff1a;TDM - 知乎&#xff09;可以对ram的多拍连续访问。 mem_bypass技术的核心就是在下一次的读前&#xff0c;可以cover 上一次的写。 如下图所示&#xff08;读延时为3cycle&#xff09;&#xff1a; 时序1 &am…

ROS路由器环回脚本,实际在用,只需要更新一个IP地址

实际在用的脚本&#xff0c;需要ros版本较高&#xff0c;低版本可以照着自己改改用&#xff0c;亲测可以。 #取当前拨号ip地址 :global ednsiph [ /ip address get [/ip address find interface"pppoe-out1" ] address ] :global newip [:pick \$ednsiph 0 [:find \…

【chromium】windows 获取源码到本地

从github的chromium 镜像git clone 到2.5G失败了官方说不能,要去 windows_build_instructions vs2017和19都是32位的 vs2022是x64的 vs2022_install You may also have to set variable vs2022_install to your installation path of Visual Studio 2022,

移动中兴ZXHN F6610M光猫拨号密码查询

宽带到期&#xff0c;移动新换了个光猫&#xff0c;型号中兴ZXHN F6610M 光猫默认提供了user账号&#xff0c;但是这个账号基本只有查看权限。 超级账号CMCCAdmin aDm8H%MdA密码并不管用。 问装维&#xff0c;装维不给&#xff0c;曲线救国通过某二手平台查到了。 1.通过超密…

windows操作系统通过浏览器调用本地程序

通过浏览器调用本地程序通常被认为是危险的行为&#xff0c;是被禁止的&#xff0c;但在基于B/S架构的一体机项目中会用到关闭或重启操作系统的操作。此时需要在前端页面有相应的功能按钮并能实现相应的功能。 通过浏览器调用本地应用程序通常需要使用浏览器扩展或本地应用程序…

Transformer(二)—— ResNet(残差网络)

Transformer&#xff08;二&#xff09;—— ResNet&#xff08;残差网络&#xff09; 一、背景1.1 梯度消失/爆炸1.2 网络退化(Degradation) 二、思路2.1 为什么需要更深的网络2.2 理想中的深网络表现 三、实践和实验效果3.1 构造恒等映射&#xff1a;残差学习&#xff08;res…

AIRIOT训练营沈阳站圆满结束|手把手教你搞定物联网应用开发

8月28日-9月1日&#xff0c;由航天科技控股集团有限公司&#xff08;以下简称“航天科技”&#xff09;主办的《AIRIOT物联网平台应用与实战》训练营在沈阳圆满结束&#xff0c;来自上海电机学院、中渝软通信息技术、北京华天机电研究所、北京环卫集团、 中国恩菲 等多家企业…

easypoi模板导出、一张sheet有多个不同表格、带一张或多张echars图表

前言 昨天遇到个有点复杂的excel需要导出&#xff0c;一张sheet里面有两个不同的表格&#xff0c;然后还有几张echars图表要加进去。总共分为上下两个部分&#xff0c;上面是表格一&#xff1b;下面又分为左右两个部分&#xff0c;左边是表格二&#xff0c;右边是几张echars图…

过等保三级的好处是什么?谁能简单说说?

虽然国家已经严格落地执行了等保2.0政策&#xff0c;但还有少数小伙伴对于等保政策不是很了解&#xff0c;有小伙伴问过等保三级的好处是什么&#xff1f;谁能简单说说&#xff1f;这里就来一起聊聊。 过等保三级的好处是什么&#xff1f; 好处1、遵循国家法律法规要求&…

气象观测站:观测原理及优势,助力气象精准预报

随着全球气候变化日益严重&#xff0c;气象观测站在现代社会中的地位愈发凸显。 一、气象观测站的观测原理 气象观测站主要通过各种传感器来测量大气的温度、湿度、风速、风向、气压、太阳辐射等基本气象要素。这些传感器需要具备高精度和高稳定性&#xff0c;以确保观测数据…

DAY02_瑞吉外卖——完善登录功能新增员工员工分页查询启用/禁用员工账号编辑员工信息

目录 1. 完善登录功能1.1 问题分析1.2 思路分析1.3 代码实现1.4 功能测试 2. 新增员工2.1 需求分析2.2 数据模型2.3 程序执行流程2.4 代码实现2.5 功能测试2.6 全局异常处理2.6.1 思路分析2.6.2 全局异常处理器2.6.3 测试 3. 员工分页查询3.1 需求分析3.2 程序执行流程3.2.1 页…

实现在外网SSH远程访问内网树莓派的详细教程

文章目录 如何在局域网外SSH远程访问连接到家里的树莓派&#xff1f;如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar4.2 cpolar进行token认证4.3 配置cpol…

PyTorch深度学习实战(15)——迁移学习

PyTorch深度学习实战&#xff08;15&#xff09;——迁移学习 0. 前言1. 迁移学习1.1 迁移学习基本概念1.2 迁移学习的重要性1.3 ImageNet1.4 迁移学习流程 2. VGG16 架构3. 使用预训练 VGG16 模型实现猫狗分类小结系列链接 0. 前言 迁移学习( Transfer Learning )是一种利用从…

利用evo将kitti数据集真值轨迹由kitti格式转为tum格式

&#xff08;1&#xff09;首先是序列对应问题&#xff1a; 00: 2011_10_03_drive_0027 01: 2011_10_03_drive_0042 02: 2011_10_03_drive_0034 03: 2011_09_26_drive_0067 04: 2011_09_30_drive_0016 05: 2011_09_30_drive_0018 06: 2011_09_30_drive_0020 07: 2011_09_30_dr…

精品基于NET实现的期刊订购管理系统

《[含文档PPT源码等]精品基于NET实现的期刊订购管理系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发软件&#xff1a;VS 2017 &#xff08;版本2017以上即可&#xff0c;不能低于2017&#xff09; 数…

12.示例程序(定时器定时中断定时器外部时钟)

目录 定时中断和时钟源选择相关库函数使用 1.定时器初始化配置 2.参数&#xff08;PSC、ARR等&#xff09;更改函数&#xff08;在程序运行过程中修改&#xff09; 3.使用定时器库函数的一些细节 定时器定时中断实例 定时器外部时钟选择 知识点get&#xff1a; 滤波器工作…