在一个字符串中查找最长的回文子串
- 格式:doc
- 大小:31.00 KB
- 文档页数:1
C程序经典算法50例1.二分查找算法:在有序数组中查找指定元素。
2.冒泡排序算法:通过不断比较相邻元素并交换位置,将较大的元素向后冒泡。
3.快速排序算法:通过选择一个基准元素,将数组分割为左右两部分,并递归地对两部分进行快速排序。
4.插入排序算法:将数组划分为已排序和未排序两部分,每次从未排序中选择一个元素插入到已排序的合适位置。
5.选择排序算法:遍历数组,每次选择最小元素并放置在已排序部分的末尾。
6.希尔排序算法:将数组按照一定间隔进行分组并分别进行插入排序,然后逐步减小间隔并重复这个过程。
7.归并排序算法:将数组递归地划分为两部分,然后将两个有序的部分进行合并。
8.桶排序算法:将元素根据特定的映射函数映射到不同的桶中,然后对每个桶分别进行排序。
9.计数排序算法:统计每个元素的出现次数,然后根据计数进行排序。
10.基数排序算法:从低位到高位依次对元素进行排序。
11.斐波那契数列算法:计算斐波那契数列的第n项。
12.阶乘算法:计算给定数字的阶乘。
13.排列问题算法:生成给定数组的全排列。
14.组合问题算法:生成给定数组的所有组合。
15.最大连续子序列和算法:找出给定数组中和最大的连续子序列。
16.最长递增子序列算法:找出给定数组中的最长递增子序列。
17.最长公共子序列算法:找出两个给定字符串的最长公共子序列。
18.最短路径算法:计算给定有向图的最短路径。
19.最小生成树算法:构建给定连通图的最小生成树。
20.汉诺塔算法:将n个圆盘从一个柱子移动到另一个柱子的问题。
21.BFS算法:广度优先算法,用于图的遍历和查找最短路径。
22.DFS算法:深度优先算法,用于图的遍历和查找连通分量。
23.KMP算法:字符串匹配算法,用于查找一个字符串是否在另一个字符串中出现。
24.贪心算法:每次都选择当前情况下最优的方案,适用于求解一些最优化问题。
25.动态规划算法:将一个大问题划分为多个子问题,并通过子问题的解求解整个问题,适用于求解一些最优化问题。
leetcode之最长回⽂⼦串Golang(马拉车算法Manacher‘sAlgorithm)最开始尝试的是暴⼒破解的⽅法求最长的回⽂⼦串,可是总是超时,因为暴⼒破解⽅法的时间复杂度是O(N3)然后去查了⼀下求回⽂⼦串的⽅法,发现了这个马拉车算法(Manacher's Algorithm)马拉车算法求最长的回⽂⼦串的时间复杂度是O(N)奇数化字符串回⽂字符串有奇偶两种形式:a aba bb abba所以为了避免我们在算法中对奇偶两种形式分开讨论,我们就将这两种形式都转化为奇数形式(也就是回⽂串的总的字符数是奇数个),⽅法就是在每个字符之间的空隙之间加⼊特殊字符,例如: a ==> #a#aba ==> #a#b#a#bb ==> #b#b#因为字符数加上他们之间的空隙数的总数总是为奇数(空隙数⽐字符数多⼀个,两个相邻的数字加起来和为奇数),所以通过这种⽅式,我们可以将字符串处理为总数为奇数回⽂串的半径通过上⾯我们的处理以后,我们在定义回⽂串的半径,也就是回⽂串长度的⼀半#a# ==> 半径为2#a#b#a# ==> 半径为4半径就是奇数回⽂串的长度加1,然后除以2得到的结果通过我们处理以后的回⽂串的半径,我们能够很容易的得到原来回⽂串的长度,原来回⽂串的长度就是处理后的回⽂串的半径减1,例如:#a# ==> 半径为2 ==> 原来回⽂串的长度为2-1=1#a#b#a# ==> 半径为4 ==> 原来回⽂串的长度为4-1=3#b#b# ==> 半径为3 ==> 原来回⽂串的长度为3-1=2有了回⽂串的长度,我们只需要知道在最开始的字符串中那个回⽂⼦字符串的起始的位置,我们就能够轻松求得回⽂⼦串,如图所⽰,第⼀⾏表⽰字符串中每个元素的下标,第⼆⾏是处理后的字符串,第三⾏表⽰以当前字符为中⼼的回⽂串的半径(例如以下标为1的b为中⼼的回⽂串是#b#,那么他的半径就是2)原始的字符串babb,对于原来是偶数的回⽂⼦串bb,如图所⽰,下标为6的#就是这个回⽂⼦串的中⼼,⽤下标6减去对应的半径3,结果为3,刚好是回⽂⼦串bb在原始字符串babb中的位置但是如果是原来是奇数的回⽂串,例如bab,那么中⼼字符在图中对应的就是下标为3的值,它的半径为4,如果相减就得到-1,显然这个-1不会是任何⼦串在原始字符串中起始位置。
找出⼀个字符串中最长连续相同⼦串题⽬:找出⼀个字符串中最长连续相邻⼦串,⽐如ababcabc,最长连续字串是abc。
分析:第⼀步,⾸先定义⼀个指针pStr定位于字串⾸部,再定义⼀个指针qStr指向pStr的下⼀个,然后qStr++找出与*pStr相同的字符;第⼆步,如果找到*qStr==*pStr,则递增两个指针,并计算下相同字符的数⽬num和这段相同⼦字符串的index。
第三步,如果*qStr!=*pStr,则设置num=0。
接着转向第⼀步...第四步,定义⼀个maxNum和⼀个maxIndex,记录最长⼦字符串的长度和位置。
如果⼀个新的num>maxNum,则maxNum=num,maxIndex=index。
#include <iostream>using namespace std;void FindStr(char* str){if(str == NULL)return;char* pStr = str;char* qStr = str+1;char* index = str;char* maxIndex = str;int num = 0;int maxNum = 0;while(*pStr != '\0'){while(*qStr != *pStr){num = 0;qStr++;}while(*qStr == *pStr && *pStr !='\0' && *qStr !='\0'){num++;index = pStr;qStr++;//千万不要放在if(...)中pStr++;}if(num>=1)index = index-num+1;if(num > maxNum){maxNum = num;maxIndex = index;}// pStr++;qStr = pStr+1;}cout << "Result: ";for(int i=0;i<maxNum;++i)cout << *maxIndex++ << ' ';cout << endl;}int main(){char* str = "abcabcdabcd";FindStr(str);return0;}。
计算机二级考试题目构成
1.基础编程题:编写一个程序,求给定数组中的最大值和最小值。
2.数据结构题:给定一个整数数组,设计一个算法,找到数组中第k
小的数。
3. 数据库题:在一个名为"students"的数据库表中,有两个字段分
别为"name"和"score",请编写一条SQL查询语句,找出所有分数在90分
以上的学生。
4.网络通信题:解释什么是TCP/IP协议,并描述其在网络通信中的
作用。
5.操作系统题:描述进程调度算法中的抢占式调度和非抢占式调度的
区别,以及各自的优缺点。
7.编程语言题:分别解释动态类型和静态类型语言,并列举各自的优
缺点。
8.算法题:设计一个算法,找到一个字符串中最长的回文子串。
9.编译原理题:解释什么是词法分析器,以及其在编译过程中的作用。
10.数据结构题:设计一个数据结构实现LRU(最近最少使用)缓存
淘汰策略。
算法特征例题
一道算法特征的例题是:
给定一个字符串s,找到其中最长的回文子串。
例如,对于字
符串"babad",其最长的回文子串为"bab"或"aba"。
解决该问题的一个算法特征是动态规划。
具体做法是,使用一个二维数组dp[i][j]来表示字符串s从索引i到j的子串是否为
回文串。
初始时,所有的dp[i][j]都设为false。
然后,从长度为1的子串开始,逐步增加子串的长度,直到整个字符串。
在每个长度下,再遍历所有可能的子串起始索引i,判断子串s[i:j]是否为回文串。
具体判断的方法是,如果s[i]等于s[j]且子串s[i+1:j-1]也为回
文串(即dp[i+1][j-1]为true),则dp[i][j]也为true。
在遍历的过程中,记录最长的回文子串的起始索引和长度,以及每次更新最长子串时的起始索引和长度,最终得到最长回文子串。
该算法的时间复杂度为O(n^2),其中n为字符串s的长度。
xxx算法题暴力解法1. 背景介绍在算法和数据结构领域,经常会遇到一些有挑战性的问题需要解决。
解决这些问题需要深厚的理论基础和丰富的实践经验。
其中,一个常见的解题方法就是暴力解法。
在本文中,我们将讨论xxx算法题,并介绍如何使用暴力解法来解决这个问题。
2. 问题描述xxx算法题是一个关于字符串操作的问题。
给定一个字符串s,我们需要找到 s 中最长的回文子串。
回文串指的是一个正读和倒读都一样的字符串。
字符串 "level" 是一个回文串。
我们需要编写一个算法来找到给定字符串中的最长回文子串。
3. 暴力解法暴力解法是一种朴素的解题方法,通常是最容易想到的方法。
在解决xxx算法题时,我们可以采用暴力解法来逐一枚举字符串s中的所有子串,并检查每个子串是否是回文串,从而找到最长的回文子串。
4. 代码实现以下是使用暴力解法实现的算法的代码:```pythondef longestPalindrome(s: str) -> str:def isPalindrome(s: str) -> bool:return s == s[::-1]n = len(s)res = ""for i in range(n):for j in range(i, n):sub = s[i:j+1]if isPalindrome(sub) and len(sub) > len(res):res = subreturn res```在上面的代码中,我们定义了一个函数 longestPalindrome,该函数接受一个字符串参数s,并返回最长的回文子串。
我们首先定义了一个辅助函数 isPalindrome,用于检查一个字符串是否是回文串。
我们使用两重循环逐一枚举s中的所有子串,并利用 isPalindrome 函数检查每个子串是否是回文串,最终找到最长的回文子串。
5. 性能分析尽管暴力解法在实现上比较简单直观,但其时间复杂度为O(n^3),空间复杂度为O(1),其中n为字符串s的长度。
dfa经典案例以下是15个DFA(确定性有限自动机)经典案例:确定型有限自动机(DFA):一个经典的例子是识别由0和1组成的字符串是否只包含一个数字。
比如,一个DFA可以识别输入的字符串是否只包含数字00-99之间的数字。
识别是否为一个有效的括号序列:使用DFA可以判断一个由“{”,“}”,“(”,“)”组成的字符串是否为有效的括号序列。
例如,输入的字符串为“()”或“(()”或“((()))”或“{()}”都是有效的,但“(({()))”或“(()){}”都是无效的。
识别单词是否为回文字符串:可以使用DFA来识别一个单词是否是回文的。
识别一个字符串是否是交替的“01”序列:DFA可以识别一个字符串是否由交替的0和1组成。
识别一个字符串是否是一个质数:DFA可以识别一个字符串是否表示一个质数。
识别一个字符串是否是一个阿姆斯特朗数:DFA可以识别一个字符串是否表示一个阿姆斯特朗数。
识别一个字符串是否是一个水仙花数:DFA可以识别一个字符串是否表示一个水仙花数。
识别一个字符串是否是一个卡布奇诺数:DFA可以识别一个字符串是否表示一个卡布奇诺数。
识别一个字符串是否是一个完全平方数:DFA可以识别一个字符串是否表示一个完全平方数。
确定一个字符串中的最长重复子串:DFA可以用来确定一个字符串中的最长重复子串的长度。
确定一个字符串中的最长回文子串:DFA可以用来确定一个字符串中的最长回文子串的长度。
确定一个字符串中的最长公共子串:DFA可以用来确定两个字符串之间的最长公共子串的长度。
确定一个字符串中的最长递增子串:DFA可以用来确定一个字符串中的最长递增子串的长度。
确定一个字符串中的最长递减子串:DFA可以用来确定一个字符串中的最长递减子串的长度。
词法分析器的设计:在编译原理中,词法分析器是一个将输入的字符流转化为记号流的有限自动机,记号是一些有意义的单词或符号。
例如,词法分析器可以识别输入的字符流中的关键字、标识符、运算符、常量等记号,并输出相应的记号流。
Python算法面试八股文汇总一、介绍在当前的科技行业中,算法面试成为了很多技术岗位的必备环节。
尤其是对于 Python 程序员来说,算法面试更是必不可少的一环。
掌握一些常见的 Python 算法面试题,成为了每一位 Python 程序员必须要做的功课。
本文将为大家汇总一些常见的Python 算法面试八股文,帮助大家系统地复习和准备算法面试。
二、数组1. 两数之和在给定的整数数组中,找到两个数使它们的和等于一个特定的目标值。
可以假设每个输入只对应一个答案,且同样的元素不能被重复利用。
这个问题可以使用暴力枚举或者哈希表进行解答。
我们可以通过遍历数组,寻找目标值与当前元素的差值是否在哈希表中,如果是则返回结果。
2. 移动零给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
解决这个问题的关键在于双指针法。
我们可以使用两个指针,一个用来遍历数组,一个用来记录非零元素的位置。
遍历数组时,将非零元素与记录非零位置的元素交换,从而实现将所有非零元素移到数组的前端。
三、字符串1. 反转字符串编写一个函数,将输入的字符串反转过来。
输入字符串以字符数组char[] 的形式给出。
解决这个问题可以使用双指针法。
我们可以用两个指针分别指向字符串的首尾,依次交换它们所指向的元素,直到两个指针相遇为止,即可完成字符串的反转。
2. 字符串中的第一个唯一字符给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。
如果不存在,则返回 -1。
解决这个问题可以使用哈希表来记录字符出现的次数。
首先遍历整个字符串,将每个字符和它出现的次数记录在哈希表中。
然后再次遍历字符串,查找第一个出现次数为1的字符即可。
四、链表1. 反转链表反转一个单链表。
解决这个问题的经典方法是使用迭代或递归。
在迭代方法中,我们需要定义三个指针分别指向当前节点、其前驱节点和后继节点,然后不断地改变指针的指向,直到链表被完全反转。
ManachersAlgorithm马拉车算法这个马拉车算法 Manacher‘s Algorithm 是⽤来查找⼀个字符串的的线性⽅法,由⼀个叫 Manacher 的⼈在 1975 年发明的,这个⽅法的最⼤贡献是在于将时间复杂度提升到了线性,这是⾮常了不起的。
对于回⽂串想必⼤家都不陌⽣,就是正读反读都⼀样的字符串,⽐如 "bob", "level", "noon" 等等,那么如何在⼀个字符串中找出最长回⽂⼦串呢,可以以每⼀个字符为中⼼,向两边寻找回⽂⼦串,在遍历完整个数组后,就可以找到最长的回⽂⼦串。
但是这个⽅法的时间复杂度为 O(n*n),并不是很⾼效,下⾯我们来看时间复杂度为 O(n)的马拉车算法。
由于回⽂串的长度可奇可偶,⽐如 "bob" 是奇数形式的回⽂,"noon" 就是偶数形式的回⽂,马拉车算法的第⼀步是预处理,做法是在每⼀个字符的左右都加上⼀个特殊字符,⽐如加上 '#',那么bob --> #b#o#b#noon --> #n#o#o#n#这样做的好处是不论原字符串是奇数还是偶数个,处理之后得到的字符串的个数都是奇数个,这样就不⽤分情况讨论了,⽽可以⼀起搞定。
接下来我们还需要和处理后的字符串t等长的数组p,其中 p[i] 表⽰以 t[i] 字符为中⼼的回⽂⼦串的半径,若 p[i] = 1,则该回⽂⼦串就是 t[i] 本⾝,那么我们来看⼀个简单的例⼦:# 1 # 2 # 2 # 1 # 2 # 2 #1 2 1 2 5 2 1 6 1 2 3 2 1为啥我们关⼼回⽂⼦串的半径呢?看上⾯那个例⼦,以中间的 '1' 为中⼼的回⽂⼦串 "#2#2#1#2#2#" 的半径是6,⽽未添加#号的回⽂⼦串为"22122",长度是5,为半径减1。
先讲一下自己的思想:
1. 设置三个指针ppre,pre,post,依次指向字符串第一个,第二个,第三个。
判断第一个和第二个(回文子串长度为偶数时);判断第一个和第三个(回文子串长度为奇数时)。
设置一个num[SIZE]数组记录回文子串的长度,一个ptr[SIZE]指针数组记录回文子串的第一个子串。
2. 首先将字符串小于3的情况进行处理,然后大于等于3时,将ppre,pre,post依次赋值。
3. 设置循环,先判断ppre和post是否相等。
若相等,就将ppre--和post++继续进行比较;不相等时,跳出,并将post值复原。
再判断pre和post的值是否相等,若相等,就将pre--和post++继续进行比较;不相等时,跳出,并将post值复原。
以上两个跳出后,注意记录回文子串的长度和首地址到num[SIZE]和ptr[SIZE]中。
完成后,将ppre,pre和post依次向前走一步,继续。
4. 最后将记录的值赋值到str中。
程序中的一个bug时,当遇到相同长度的回文字串时,输出第一个回文子串。
1。