在Java中字符串内容是不可变的,也就是说如果想对字符串做出改变,那么需要用返回值来接收新的字符串,一旦对字符串内容做出了改变,就会产生一个新的字符串实例,例如:
String str="hello";
str.toUpperCase();
虽然对str做了toUpperCase的操作,但是操作的结果是产生一个新的String,str的结果不会发生变化 依旧是hello小写,这就产生了一个问题,对于String的操作,每次操作结果都会产生一个新的临时对象,开销太大,因此经常使用StringBuffer是一个好习惯。StringBuffer是可变类对象,通过new关键字创建,对象创建后会在初始为null,并通过append方法来修改该对象。
字符串常见面试题
最大相邻的非重复的字符串长度
问题描述:Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for “abcabcbb” is “abc”, which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1.
问题求解思路:对于最大的非重复字符串长度,首先遍历字符串,在第i个位置时,判断第i个位置的字符在之前是否出现过,在这里使用到的数据结构为HashMap
public int lengthOfLongestSubstring(String s) {
int leftBound=0;
int max=0;
HashMap<Character,Integer> map=new HashMap<Character,Integer>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
leftBound=Math.max(leftBound, map.containsKey(ch)?map.get(ch)+1:0);
max=Math.max(max, i-leftBound+1);
map.put(ch, i);
}
return max;
}
乱序字符串
问题描述:给出一个字符串数组S,找到其中所有的乱序字符串(Anagram)。如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中,样例:对于字符串数组 [“lint”,”intl”,”inlt”,”code”] 返回 [“lint”,”inlt”,”intl”]
问题分析:这个问题关键点有两个,第一个是如何判别两个顺序不同但是字母组成相同的字符串,很直接的方法就是将不同的顺序转化成相同的顺序,如果完全相同则是乱序字符串,因此可以按照字母表的顺序将所有的字符串重新排序,如果是乱序字符串则重新排序后完全相同,此时可以用ArrayList存储各个转化后的字符串,之后重新遍历一边数组,如果将转化后的字符串与ArrayList中存储的字符串比较,第一次出现和最后一次出现的位置不同 ,则说明它是乱序字符串
public List<String> anagrams(String[] strs) {
List<String> re=new ArrayList<>();
List<String> result=new ArrayList<>();
if(strs.length==0){
return re;
}
for(int i=0;i<strs.length;i++){
re.add(fromArrayToString(strs[i]));
}
for(int i=0;i<strs.length;i++){
String index=strs[i];
if(re.indexOf(fromArrayToString(index))!=re.lastIndexOf(fromArrayToString(index))){
result.add(index);
}
}
return result;
}
public static String fromArrayToString(String str){
char[] arrays=str.toCharArray();
Arrays.sort(arrays);
String re=String.copyValueOf(arrays);//注意如果想要把char数组转化为String需要使用String.copyValueof函数,而不是arrays.toString()
return re;
}
翻转字符串
问题描述:Given an input string, reverse the string word by word.
For example,
Given s = “the sky is blue”,
return “blue is sky the”.
问题解析:该问题本身没有难度,关键在于边界值的确定,例如如果输入的是“ ”,或者“ ”,总之就是输入中只有若干个空格的情况,要注意如何处理。
public String reverseWords(String s) {
String re="";
String[] words=s.split(" ");
for(int i=words.length-1;i>=0;i--){
re=re+words[i]+" ";
}
if(re==""){
return re;
}else{
return re.substring(0, re.lastIndexOf(" "));
}
}
判断一个字符串是否为回文串
问题描述:给定一个字符串,判断其是否为一个回文串。只包含字母和数字,忽略大小写。”A man, a plan, a canal: Panama” 是一个回文。”race a car” 不是一个回文。
问题分析:首先要把所有的非数字和字母都删去,其次要把字母都转化为小写,最后是对于“ ”的单独处理
if(s==""){
return true;
}
String b=s.replaceAll("[^0-9A-Za-z]", "");
String a=b.toLowerCase();
for(int i=0;i<a.length()/2;i++){
if(a.charAt(i)!=a.charAt(a.length()-1-i)){
return false;
}
}
return true;
}