通俗易懂的最长回文串图解、说明及Java代码(中心扩散法和Manacher算法)

本文介绍了回文串的概念,包括奇回文和偶回文。接着讨论了如何找到字符串中的最长回文串,分别阐述了暴力匹配法、中心扩散法的时间复杂度和实现思路,并重点解析了Manacher算法,包括其预处理步骤、回文半径记录以及优化策略。通过Manacher算法,可以在O(n)时间复杂度内求解最长回文串。
摘要由CSDN通过智能技术生成

1. 回文串

作为程序员,回文串这个词已经见怪不怪了,就是一个字符串正着读和反着读是一样的,形式如abcdcba、bbaabb。这里涉及到奇回文偶回文,奇回文指回文串的字符数是奇数,偶回文指回文串的字符数是偶数。前面举的abcdcba就是奇回文,bbaabb就是偶回文。判断一个字符串是否是回文串很简单,只要从字符串的两端开始往中间扫描,全部匹配成功则是回文串,只要有一次匹配失败,那么就不是回文串。代码如下

// 没有对字符串为null或者空串的返回值进行考虑
static boolean Palindrome(String s){
    for(int i = 0, j = s.length()-1; i < j; i++, j--){
        if(s.charAt(i) != s.charAt(j)){
            return false;
        }
    }
    return true;
}

 

2. 最长回文串

在我们了解回文串内容后,如果给你一个字符串,你能不能得到该字符串中的最长回文串呢?

2.1 暴力匹配法

最长回文串简单的解法就是暴力匹配法,依次判断所有字符数大于1个的子串是否回文串,并记录最长的那个回文串。如acbc字符串,得到字符数大于1的子串ac、cb、bc;acb、cbc;acbc,其中cbc是最长回文串。虽然暴力匹配法思路清晰、代码简单,但是如果字符串长度较长时,那么子串的数量是很庞大的,对于一个长度为n的字符串,它的子串有n(n-1)/2个,加上判断子串是否为回文串的时间复杂度是O(n),所以最终总的时间复杂度是O(n^3)左右。暴力匹配留给大家自行编写代码,博主就偷个懒不写了。

2.2 中心扩散法

中心扩散法是另一种回文串解决方法,算法思路是从字符串的第一个字符一直遍历到最后一个字符,每次从该字符往两边扫描,如果左右两边的值相等,那么往左右两边拓展,直至左右两边的值不相等或者越界,扫描结束,记录此时的左右边界下标,并且记录此时的回文串长度。该方法的时间消耗主要是遍历字符串的每个字符,以及每个字符需要向两边拓展扩散,所以总的时间复杂度为O(n^2)

图解:以下以abcfcbd字符串遍历到 f 字符进行图解,如下图。

1. 当遍历abcfcbd字符串的 f 字符时,先令left和right都指向 f 字符。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
快速排序是一种常用的排序算法,它的基本思想是通过一趟排序将待排序记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后分别对这两部分记录继续进行排序,重复以上步骤,直到整个序列有序。 简单来说,就是将一个无序的序列分成两部分,一部分比另一部分小,然后对这两个部分分别进行快速排序,最终得到一个有序序列。 下面是java的快速排序代码实现: ``` public class QuickSort { public static void quickSort(int[] arr, int left, int right) { if (left < right) { int pivotIndex = partition(arr, left, right); quickSort(arr, left, pivotIndex - 1); quickSort(arr, pivotIndex + 1, right); } } private static int partition(int[] arr, int left, int right) { int pivot = arr[left]; int i = left + 1; int j = right; while (true) { while (i <= j && arr[i] < pivot) { i++; } while (i <= j && arr[j] > pivot) { j--; } if (i >= j) { break; } swap(arr, i, j); } swap(arr, left, j); return j; } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { int[] arr = {5, 3, 7, 2, 8, 4, 1, 6}; quickSort(arr, 0, arr.length - 1); System.out.println(Arrays.toString(arr)); } } ``` 以上代码实现了快速排序的算法,其中partition方用来找到基准点(pivot)的位置,swap方用来交换数组中两个元素的位置。在main方中,我们给出一个待排序的数组,然后调用quickSort方进行排序,最后输出排序后的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值