这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
前言
String字符串在我们开发中非常高频出现的一种数据结构,我这里准备了几道小题,不管你是初学者还是专家,都可以试试是否可以很容易的解决下面几道题,如果你有更好的解决办法,欢迎在评论去交流!
- 如何不使用Java内建方法反转一个字符串?
- 写一个java程序检查两个字符串是异位词?【异位词是指相同字符不同位置】
- 判断一个字符串中的所有字符是否只出现一次?
- 如何从字符串中找到重复的字符?
- 找到字符串的所有子字符串?
- 找出一个输入字符串的所有排列可能?
再开始看下面的解法前不妨自己先想一想这几道题都应该怎么解决,然后看看下面的方法是不是和你想的一致,如果你的方法更好,欢迎在评论区留言。
如何不使用Java内建方法反转一个字符串?
解决这个问题有三种方式:
- 使用循环
- 使用递归
- 使用StringBuilder、StringBuffer
使用for循环
思路:
- 声明一个空String变量,用来保存最终反转的字符串;
- 使用for循环遍历要反转的字符串,从最后一个位置到第0个位置;
- 在遍历时将字符添加到声明的空String变量上。
1 | java复制代码public class ReverseStringForMain { |
使用递归
思路:
- 如果字符串长度为1,则反转结果为该字符串本身;
- 如果字符串长度大于1,则反转结果为该字符串的最后一个字符加剩余字符串的反转结果。
1 | java复制代码public class ReverseStringRecursive { |
使用StringBuffer
使用StringBuffer的reverse方法,同样可以实现字符串的反转功能。
1 | java复制代码public class StringBufferReverse { |
写一个java程序检查两个字符串是异位词?
说明:异位词是指两个单词有相同的字母,但是顺序不同,如: Angel 和Angle。
这道题有多种解决方式:
- 使用String类的方法
- 使用Arrays.sort()
- 使用计数数组
- 使用Guava的Multiset
使用String类方法
思路:
- 建立一个方法,接收两个字符串变量,用来判断是否是异位词;
- 迭代第一个String单词,并使用charAt()方法从中获得char c;
- 如果第二个String单词的indexOf(c)的值等于-1,那么两个字符串不是字谜;
- 如果第二个String单词的indexOf(c)的值不等于-1,那么从第二个单词中删除字符c;
- 如果第二个String单词最后是个空字符串,则代表两个单词是异位词。
1 | java复制代码public class StringAnagramMain { |
使用Arrays.sort()
思路:直接对两个字符串排序,如果排序之后两个字符串相等,则表示两个字符串是异位词。
1 | java复制代码public class AnagramUsingSort { |
使用计数数组
思路:
- 如果两个字符串长度不同,则不是异位词;
- 创建一个长度为256的数组;
- 迭代第一个字符串str1;
- 在每次迭代中,我们递增第一个String str1的计数,递减第二个String str2的计数;
- 如果任何字符的count在末尾不为0,则表示两个string不是字谜。
这种方法的时间复杂度是O(n),但它需要额外的空间计数数组。
1 | java复制代码public class AnagramCountingMain { |
使用Guava的Multiset
如果您喜欢使用Guava库,那可以使用MultiSet来检查两个String是否为异位词。
MultiSet允许每个元素出现多次,并记录每个元素的计数。
当然这种方式需要在pom.xml添加Guava依赖。
1 | xml复制代码<dependency> |
代码如下:
1 | java复制代码import com.google.common.collect.HashMultiset; |
判断一个字符串中的所有字符是否只出现一次?
说明:比如Apple
单词中字符p
出现多次,所以不符合;world
中所有单词都只出现一次,所以符合。
这道题有以下几种解决方法:
- 使用HashSet
- 使用indexOf和lastIndexOf方法
- 使用字符的ascii值
使用HashSet
依赖于HashSet的add()方法,如果已存在的元素会返回false。
步骤:
- 遍历每个字符,添加到HashSet;
- 如果HashSet的add方法返回false,那么它不是所有的唯一字符。
1 | java复制代码public class StringAllUniqueCharMain { |
使用indexOf和lastIndexOf方法
思路:如果indexOf和lastIndexOf对字符返回相同的值,则在该字符串中不会重复。
1 | java复制代码public class StringAllUniqueCharMain { |
使用字符的ascii值
这个方法是最高效的。
思路:
- 创建一个长度为26的布尔数组;
- 将char转换为大写并获取其ascii值;
- 将64减去ascii值以获得0到25之间的索引;
- 如果字符不重复,则布尔数组中应该有false;
1 | java复制代码public class StringAllUniqueCharMain { |
如何从字符串中找到重复的字符?
思路:
- 创建一个HashMap,创建一个HashMap,字符串字符将作为key插入,其计数作为value插入;
- 如果HashMap已经包含char,则将其计数增加1,否则将char放入HashMap中;
- 如果Char的值大于1,这意味着它是该字符串中的重复字符。
1 | java复制代码import java.util.HashMap; |
找到字符串的所有子字符串?
例如:如果输入是abb,那么输出应该是a, b, b, ab, bb, abb
思路:使用String类的subString方法来查找所有subString。
1 | java复制代码class SubstringsOfStringMain{ |
这个解决办法的时间复杂度为O(n^3)
。因为我们有两个循环而且String
的子字符串方法的时间复杂度是O(n)
如果想找到String的所有不同的子字符串,那么需要使用HashSet
来删除重复的字符串。
找出一个输入字符串的所有排列可能?
比如:输入“AB”,输出[“AB”,”BA”],输入“ABC”,输出[“ABC”,”ACB”,”BAC”,”BCA”,”CBA”,”CAB”]。
思路:
- 取出String的第一个字符,递归输入剩余String的排列的不同位置;
- 假设输入String为ABC,取出第一个字符”A”;
- 从BC中取出B,将剩余字符串”C”递归输入;
- String长度为1时,返回,所以返回“C”;
- 将取出的“B”分别插入到递归返回结果的字符串的每一个位置;
- 这时得到BC,CB,返回;
- 将取出的字符“A”分别插入返回结果的字符串的每一个位置;
- 这时得到[ABC,BAC,BCA]和[ACB,CAB,CBA];
- 最终返回结果就是ABC的所有排序。
1 | java复制代码 |
小结
以上就是本期的所有内容,怎么样,这些方法你都想到了吗?如果你有更好的方法欢迎留言交流。
如果对你有帮助,点个赞是对我最大的鼓励。
本文转载自: 掘金