Java数据结构和算法总结-字符串及高频面试题算法
前言:周末闲来无事,看了看字符串相关算法的讲解视频,收货颇丰,跟着视频讲解简单做了一下笔记,方便以后翻阅复习同时也很乐意分享给大家。什么字符串在算法中有多重要之类的大路边上的客套话就不多说了,直接上笔记吧。
一、字符串
java:String内置类型,不可更改。(如需更改可考虑:StringBuffer, StringBuilder,char[]等)
二、归类
字符串涉及到的相关题型通常会是以下几个方面:
- 概念理解:字典序
- 简单操作:插入删除字符、旋转
- 规则判断(罗马数字转换 是否是合法的整数、浮点数)
- 数字运算(大数加法,二进制加法)
- 排序、交换
- 字符计数:变位词
- 匹配(正则表达式、全串匹配、KMP、周期判断)
- 动态规划(LCS、编辑距离、最长回文子串)
- 搜索(单词变换、排列组合)
三、例题
1、交换:把一个只包含01的串排序,可交换任意两个数的位置,最少需要多少次交换?
思路:从两头往中间扫荡,扫荡过程中在左边遇到1就和右边遇到的0交换位置,直接到左有下标相遇时结束。 具体代码如下:
public static void main(String[] strs) {
int count = ;
int[] arrays = new int[] {, , , , , , , , , };
int left = ;
int right = arrays.length - ;
while (true) {
while (arrays[left] == ) {
left++;
}
while (arrays[right] == ) {
right--;
}
if (left >= right) {
break;
} else {
int temp = arrays[left];
arrays[left] = arrays[right];
arrays[right] = temp;
count++;
}
}
Logger.println("交换次数:" + count);
for (int array : arrays) {
Logger.print(array + ", ");
}
}
清晰起见,交换次数和排序后的的字符串输出如下:
交换次数:3
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2、字符串替换和复制:删除一个字符串所有的a,并且复制所有的b(字符数组足够大)
思路:详细思路见代码注释
public static void main(String[] strs) {
char[] input = new char[]{'a', 'b', 'c', 'd', 'a', 'f', 'a', 'b', 'c', 'd', 'b', 'b', 'a', 'b'};
char[] chars = new char[50];
for (int j = 0; j < input.length; j++) {
chars[j] = input[j];
}
Logger.println("操作前:");
for (char c:chars
) {
Logger.print(c + ", ");
}
int n = 0;
int countB = 0;
// 1、删除a,用n当做新下标,循环遍历数组,凡是不是a的元素都放到新下标的位置,由于新n增长慢,老下标i增长快,所以元素不会被覆盖。
// 并且在删除a时顺便记录b的数量,以便下一步复制b时可以提前确定数组最终的最大的下标。
for (int i = 0; chars[i] != '\u0000' && i < chars.length; i++) {
if (chars[i] != 'a') {
chars[n++] = chars[i];
}
if (chars[i] == 'b') {
countB++;
}
} // 2、复制b,由于在第一步中就已经知道了字符串中b的个数,这里就能确定最终字符串的最大下标,从最打下表开始倒着复制原字符串,碰到b时复制即可。
int newMaxIndex = n + countB - 1;
for (int k = n - 1; k >= 0; k--) {
chars[newMaxIndex--] = chars[k];
if (chars[k] == 'b') {
chars[newMaxIndex--] = chars[k];
}
} Logger.println("\n操作后:");
for (char c:chars
) {
Logger.print(c + ", ");
}
}
3、交换星号:一个字符串只包含 * 和数字,请把它的 * 都放在开头。
如:1 * 2 * 4 * 3 => * * * 1 2 4 3
- 方案一:倒着操作,从最大下标开始向前遍历,遇到非 * 号的元素则加入"新"下标中,遍历完毕后,j即代表 * 号的个数,然后将0-j赋值为 * 即可。(操作后,数字的相对位置不变) 代码如下:
public static void main(String[] strs) {
char[] chars = new char[]{'1', '*', '4', '3', '*', '5', '*'};
// 方案一(操作后,数字的相对位置不变)
// 倒着操作:从最大下标开始向前遍历,遇到非*号的元素则加入"新"下标中,遍历完毕后,j即代表*号的个数,然后将0-j赋值为*即可。
int j = chars.length - 1;
for (int i = j; i >= 0; i--) {
if (chars[i] != '*') {
chars[j--] = chars[i];
}
}
while (j >= 0) {
chars[j--] = '*';
}
for (char c:chars
) {
Logger.print(c + ", ");
}
}
输出结果如下:
*, *, *, 1, 4, 3, 5,
- 方案二(操作后,数组的相对位置会变)快排划分,根据循环不变式(每一步循环之后条件都成立):如本题[0..i-1]是*,[i..j-1]是数字,[j...n-1]未探测,循环时,随着i和j增加,维护此条件依然不变,代码如下:
public static void main(String[] strs) {
char[] chars = new char[]{'1', '*', '4', '3', '*', '5', '*'};
// 方案二(操作后,数组的相对位置会变)
// 快排划分,根据循环不变式(每一步循环之后条件都成立):如本题[0..i-1]是*,[i..j-1]是数字,[j...n-1]未探测,循环时,随着i和j增加,维护此条件依然不变
for (int i = 0, j = 0; j < chars.length; ++j) {
if (chars[j] == '*') {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
i++;
}
}
for (char c:chars
) {
Logger.print(c + ", ");
}
}
输出结果如下:
*, *, *, 3, 1, 5, 4,
4、单词翻转
例如:I am a student =》 student a am I
思路:
1、先将整个字符串翻转:如:I am a student =》 tneduts a ma I
2、通过空格判断出每个单词,然后对每个单词进行翻转
代码如下:
public static void main(String[] strs) {
String input = "I am a student";
char[] chars = input.toCharArray();
int i = 0;
int j = chars.length - 1;
while (i < j) {
swap(chars, i++, j--);
}
int front = 1;
int tail = 0;
while (front < chars.length) {
if (chars[front] == ' ') {
int frontTemp = front - 1;
while (tail < frontTemp) {
swap(chars, tail++, frontTemp--);
}
tail = front + 1;
}
front++;
}
for (char c:chars
) {
Logger.print(c);
}
} public static void swap(char[] chars, int index1, int index2) {
char temp = chars[index1];
chars[index1] = chars[index2];
chars[index2] = temp;
}
输出结果如下:
student a am I
5、子串变位词:给定两个串a和b,问b是否a的子串变位词。
例如:a=hello。b=lel,lle,ello都是true;b=elo是false
思路:
- 一、首先需要了解对两个串是否是变位词的判断:
- 对两个串按统一规则排序,排序后若相等则是变位词。
- 对两个串中出现的字母统计,两串中相同的字母出现的次数一致则为变位词。
- 二、然后从母串的第一个元素遍历,每往后遍历一个元素就把从当前元素开始到加上子串的长度的位置作为一个区间和子串比较是否是变位词。
最后一题综合前几个题用到的一些技巧,还是比较有趣的,这里就不贴出代码了,也激发一下大家的动手能力,感兴趣的童鞋不妨试着写一写。
以上问题如有不同思路欢迎交流。
Java数据结构和算法总结-字符串及高频面试题算法的更多相关文章
- Java数据结构和算法总结-字符串相关高频面试题算法
前言:周末闲来无事,看了看字符串相关算法的讲解视频,收货颇丰,跟着视频讲解简单做了一下笔记,方便以后翻阅复习同时也很乐意分享给大家.什么字符串在算法中有多重要之类的大路边上的客套话就不多说了,直接上笔 ...
- 2020年Java多线程与并发系列22道高频面试题(附思维导图和答案解析)
前言 现在不管是大公司还是小公司,去面试都会问到多线程与并发编程的知识,大家面试的时候这方面的知识一定要提前做好储备. 关于多线程与并发的知识总结了一个思维导图,分享给大家 1.Java中实现多线程有 ...
- xsank的快餐 » Python simhash算法解决字符串相似问题
xsank的快餐 » Python simhash算法解决字符串相似问题 Python simhash算法解决字符串相似问题
- ipv4 ipv6 求字符串和整数一一映射的算法 AmazonOrderId
字符串和整数一一映射的算法 公司每人的英文名不同,现在给每个英文名一个不同的数字编号,怎么设计? 走ipv4/6 2/32 2/128就够了,把“网段”概念对应到“表或库”,ip有a_e5类,这概念 ...
- Java数据结构和算法 - 堆
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...
- Java数据结构和算法 - 栈和队列
Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...
- Java数据结构与算法 - 外部存储
Q: 什么是外部存储? A: 外部存储特指某类磁盘系统,例如在大多数台式电脑或服务器中的硬盘. Q: 如何访问外部存储? A: 我们所学的数据结构都是假设数据存储在内存中,但是,在很多情况下要处理的数 ...
- Java数据结构和算法 - 哈希表
Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计 ...
- Java数据结构和算法(一)--栈
栈: 英文名stack,特点是只允许访问最后插入的那个元素,也就是LIFO(后进先出) jdk中的stack源码: public class Stack<E> extends Vector ...
随机推荐
- 201521123024 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容.
- latch session allocation
应用反馈上午10点左右出现大量应用连接数据库报错 采集9点-10点和10点-11点的AWR报告进行分析 DB时间明显差异,再继续分析等待事件 可以看出有session相关的Latch等待事件,查看相关 ...
- Spark Streaming socketTextStream简单demo
正文 SparkStreaming的入口是StreamingContext,通过scala实现 一个简单的实时获取数据.代码SparkStreaming官网也可以找到. object SocketDS ...
- 设置文件opendilag、savedilog默认路径和文件类型
dlgSave1.Filter:='文件.txt|*.txt;|word文件|*.doc,*.docx'; dlgSave1.InitialDir:=GetCurrentDir; //设置为当前路径 ...
- sqlserver2012 密码过期问题
昨天登录系统突然连不上数据库了看了看报错内容提示是sqlserver的用户密码过期,那么就简单记录下操作,方便孩子后解决 (1)首先打开sql Management Studio 2012 顺便提一下 ...
- 06jQuery-06-AJAX
1.JS的AJAX AJAX,Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求. 如果要让用户留在当前页面中,同时发出新的HTTP请求,就 ...
- Struts+Spring+Hibernate项目整合AJAX+JSON
1.什么是AJAX AJAX是 "Asynchronous JavaScript and XML" 的简称,即异步的JavaScript和XML. 所谓异步,就是提交一个请求不必等 ...
- 关于maven中一些问题的解决尝试
在maven中会遇到很多问题,pom.xml啊,数据库没有自动建表等等. 需要先把运行项目,所依赖的jar项目install安装一下,然后Maven --> update project 一下. ...
- layer子层给父层页面元素赋值,以达到向父层页面传值的效果
父层: jsp中: //页面上添加一个隐藏的输入框待用于被子层设置value,从而将子层的数据传递到此页面 <input type="hidden" id="get ...
- hadoop各个类及其作用
1.基础包(包括工具包和安全包) 包括工具和安全包.其中,hdfs.util包含了一些HDFS实现需要的辅助数据结构:hdfs.security.token.block和hdfs.security.t ...