算法之字符串题型总结

1.字符串的旋转

给定abcdef,例如把字符串的前三个字符移动到后面。形如:defabc!

解法一:暴力法

每次所有字符串向前移动一位,移动m次即可。但是复杂度为O(mn)

解法二:三步反转法(类比结构的对称性)

通过m把字符串分割成两个字符串,然后对这两个字符串分别反转。最后在对字符串整体反转。

abcdef--  ba fedc  --  cdef ab

扩展:对输入的英文单词进行反转:"i am a student." 变为 "student. a am i"!

是不是只要对每个单词翻转一次,在对整体翻转一次不就行了。

2.字符串的包含

给定长字符串a和短字符串b,要b中的元素在a中都出现过!

解法一:暴力法

枚举短字符b,判断在a中是否出现过。时间复杂度为O(m*n)

解法二:排序+暴力法

先对a和b字符排序,然后枚举b,只要a的字符大于b的字符那么就可以判断不包含,如果字符相等就下一个b字符,小于就找下一个a字符。

解法三:hash表(类似了计数排序方法)

把所有a字符都用hash表存储(用长度26的数组简单来模拟),然后遍历b字符进行查找。时间O(m+n)!

扩展:给定两个串a和b,问b是否是a的子串的变位词。例如输入a = hello, b = lel, lle, ello都是true,但是b = elo是false。

思路: 比如b的长度是3,则考察a[0..2], [1..3],[2..4]是否和b是变位词,需要hash表进行更新元素,

扩展:第一个只出现一次的字符?

思路一:暴力法是对每一个字符查找是否出现过,时间为N的平方;

思路二:哈希表可以进行加速线性时间可以完成;

3.字符串的全排列

输入字符串“abc”,按字典序排列,输出所有排列后的字符串"abc","acb","bac","bca"......

解法一:递归实现 

每次固定一个位置,然后递归下去(第一个位置,第二个.....第n个),第一个位置可放n个,第二个可放n-1个,最后一个放一个。使用交换元素的思路,要注意交换后得交换回去复原!

字符串有重复的时候,当前元素只要没有与之前对应的元素相等那么就可以交换,否则不可以,因为start位置的元素已经交换过了这个元素!

4.字符串转化成整数

直接写出代码容易:从左向右使用n = n*10 + c公式即可!

ps:要判断空,要判断正负号,要判断字符串是否合法,要判断是否会溢出。

5.判断字符数组是否所有字符都出现过一次

思路一:使用哈希表来判断是否出现了重复。

思路二:进行排序但是题目要求空间复杂度为常量,所以快排(递归和非递归版本都需要空间),归并两个较快的使用不了,只能使用非递归的堆排序了。

6.字符串的调整与替换

把字符串的空格替换为"%20",设右半区足够大

思路:遍历左半区,计算出最终一共需要的位置,然后逆序遍历进行填补。

扩展:字符串中有字符"*"要把该字符全部移动到前面。

因为不用扩充字符,所以直接逆序遍历进行判断,再把前面的空字符填补成"*"。

7.数组中两个字符的最小距离

思路:需要两个指针和一个遍历指针,分别记录字符最近一次出现的位置,每更新一次位置就计算一次最短距离。

8.添加最少字符使字符串整体都是回文子串

思路:设dp(i,j)代表字符i到j为回文串的最少添加字符数。需要注意i到j只有一个字符,i到j有两个字符的特殊情况,i到j多于两个字符为一般情况, if s(i)=s(j) dp(i,j)=dp(i+1,j-1)  if 不等,需要添加一个字符给i还是j找一个最小的即可,dp(i,j)=min(dp(i+1,j),dp(i,j-1))+1

扩展:如果需要打印出来构造的回文串,需要逆序遍历构造出来,注意判断在左边加字符还是在右边加字符。

9.回文最少分割数

思路一:使用暴力递归,每个位置分和不分,返回分割最少的即可,如果分那么前一部分必须是回文串。

思路二:dp(i)代表i到字符串结尾回文串的最少分割。在i到len中找到一个j,i到j必须为回文串找出分割最少的那个即可。dp(i)=min(dp(j+1)+1)i<=j<len。要快速判断i到j为回文串,需要构造一个数组boolean(i,j)代表i字符到j字符是否为回文串。

10.正则表达式匹配(自动机:动态规划 | DFS)

'*'表示它前面的字符可以出现任意次(包含0次)

思路:使用递归进行判断,如果当前位置的下一个元素是*,如果不是*,按这两种情况来处理。

class Solution {
public:
    bool match(char* str, char* pattern) {
        if(str==NULL||pattern==NULL)
            return false;
        return dfs(str,pattern);
    }
    bool dfs(char* str, char* pattern) {
        if(*str=='\0'&&*pattern=='\0')
            return true;
        if(*str!='\0'&&*pattern=='\0')
            return false;
        if(*(pattern+1)=='*') {
            if(*pattern==*str||(*pattern=='.'&&*str!='\0'))
                return dfs(str+1,pattern)||dfs(str,pattern+2);
            else
                return dfs(str,pattern+2);
        }
        if(*str==*pattern||(*pattern=='.'&&*str!='\0'))
            return dfs(str+1,pattern+1);
        return false;
    }
};

11.给定一个字符串,找出不含有重复字符的最长子串的长度。

思路:使用动态规划,dp(i)代表以第i个字符为结尾的最长子串,记录第i个字符最近一次出现的位置是否在dp(i-1)区域内

12.字符串匹配

思路一:KMP算法,是对暴力算法回溯的一种改进(不需要进行回溯,直接从原位进行匹配),并且新增引进了已经匹配字符串的最长公共前缀和后缀的概念(前缀和后缀相同模式串可以移位),让下一次从模式串开始匹配的位置尽可能大。

13.把一个0-1串(只包含0和1的串)进行排序,你可以交换任意两个位置,问最少交换的次数?

思路:最左边的那些0和最右边的那些1都可以不管;一个指针p1指向0的下一个字符和一个遍历指针

14.字符串的最长公共子串和最长公共子序列

公共子串

思路:都可以使用dp(i,j)来处理,代表s1以i结尾和s2以j结尾的最长公共子串;

公共子序列

思路:dp(i,j)代表s1在i和s2在j的最长公共子序列;字符相等(+1)字符不等(以每一个字符串为结尾取最大)

15.大数相加

思路:两个字符串进行相加,在返回字符串即可;处理好进位问题即可。

扩展:大数相乘

思路:按位相乘得到的结果,存起来,转化为大数相加问题

扩展:打印从 1 到最大的 n 位数

思路:每次确定一位,每次都确定为0~9直到位数够,进行打印即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java编程考试常出现的题型包括以下几种: 1. 字符串操作题:要求学生实现字符串的常见操作,比如字符串的拼接、反转、替换、查找等。此类题目考察学生对字符串的基本掌握程度以及对字符串操作方法的熟练度。 2. 线性表、栈、队列和链表题:考察学生对这些数据结构的理解和熟练应用能力,比如实现这些数据结构的基本操作、应用场景分析等。 3. 树结构题:要求学生实现二叉树的遍历、查找等操作,或者实现树的相关算法,比如构建哈夫曼树等。 4. 排序算法题:要求学生实现常见的排序算法,比如冒泡排序、快速排序、堆排序、归并排序等,并分析其时间复杂度。 5. 查找算法题:要求学生实现常见的查找算法,比如二分查找、哈希查找等,并分析其时间复杂度。 6. 分治算法题:要求学生实现常见的分治算法,比如归并排序、快速排序等,并分析其时间复杂度。 以下是一些示例题目及其答案: 1. 字符串操作题: 题目:将一个字符串中所有的空格替换为"%20"。 答案:可以先遍历字符串,记录空格的数量,然后计算出替换后的字符串长度,从后向前进行替换。 2. 线性表题: 题目:实现一个栈,要求支持入栈、出栈和获取栈顶元素的操作。 答案:可以使用数组或链表来实现栈,入栈操作即在栈顶插入元素,出栈操作即从栈顶删除元素,获取栈顶元素操作即返回栈顶元素。 3. 树结构题: 题目:实现一个二叉树的前序遍历。 答案:前序遍历的顺序是根节点、左子树、右子树。可以使用递归或者栈来实现前序遍历。 4. 排序算法题: 题目:实现一个快速排序算法。 答案:快速排序的基本思路是选择一个基准元素,将小于基准元素的数放在其左边,大于基准元素的数放在其右边,然后对左右两部分分别递归进行快速排序。时间复杂度为O(nlogn)。 5. 查找算法题: 题目:实现一个二分查找算法。 答案:二分查找的基本思路是将数组分成左右两部分,若查找元素小于中间元素,则在左半部分继续查找,否则在右半部分查找,直到找到或者查找区间为空。时间复杂度为O(logn)。 希望这些信息能够对你有所帮助,祝你考试顺利!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值