本文介绍常见的字符串编程题
反转字符串
思路:while循环遍历,交换前后对应位置元素
public void reverseString(char[] s) {
int i = 0;
int j = s.length - 1;
while (i < j) {
char temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
System.out.println(s);
}
验证回文字符串
思路:字符串翻转,equals判断相等
//替换非字符串非数字的位置(空格)
String actual = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase();
String rev = new StringBuffer(actual).reverse().toString();
return actual.equals(rev);
}
最长公共前缀
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
String pre = strs[0];
int i = 1;
while (i < strs.length) {
//循环每个字符串是否包含第一个字符串
while (strs[i].indexOf(pre) != 0) {
//如果不包含,每次舍弃最后一位
pre = pre.substring(0, pre.length() - 1);
}
i++;
}
return pre;
}
重复的子字符串
思路:两字符串相加indexof从1开始取值与字符串长度做对比
//indexof:从index的地方开始找,返回第一次出现的索引
public boolean repeatedSubstringPattern(String str) {
return (str + str).indexOf(str, 1) < str.length();
}
无重复字符的最长子串
思路:
// 滑动窗口
public int lengthOfLongestSubstring(String s) {
int i =0,j=0,max=0;
HashSet<Object> set = new HashSet<>();
while (j <s.length()){
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
max=Math.max(max,set.size());
}else {
set.remove(s.charAt(i++));
}
}
return max;
}
根据字符出现频率排序
思路:字符串转为字符数组,遍历字符数组统计字符出现的次数(放HashMap),根据出现次数做排序,遍历Map.entry输出字符串
public static String frequencySort(String s) {
HashMap<Character, Integer> map = new HashMap<>();
for (char c : s.toCharArray()) {
map.put(c, map.getOrDefault(c, 0) + 1);
}
List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
//hashmap排序
Collections.sort(list, (o1, o2) -> (o2.getValue()).compareTo(o1.getValue()));
StringBuilder stringBuilder = new StringBuilder();
for (Map.Entry<Character, Integer> entry : list) {
for (int i = 0; i < entry.getValue(); i++) {
stringBuilder.append(entry.getKey());
}
}
return stringBuilder.toString();
}
判断子序列
/*
关注点:当字符'a'出现,判断字符传t中是否存在字符'a' t中字符‘a'之后的剩余字符串是否存在’b'
核心思想:剩余字符串中是否存在下一个字符;利用贪心算法的概念就是局部是否存在最优解
贪心策略具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关
*/
public static boolean isSubsequence(String s, String t) {
if (s.length() == 0) {
return true;
}
if (s.length() == 1) {
return t.contains(s);
}
if (s.length() > 1) {
if (t.contains(s.substring(0, 1))) {
//s剩余字符串,t剩余字符串
return isSubsequence(s.substring(1), t.substring(t.indexOf(s.substring(0, 1)) + 1));
}
}
return false;
}
字符串转整数
public static int myAtoi(String str) {
str = str.trim();
if (str == null || str.length() == 0){
return 0;
}
char firstChar = str.charAt(0);
int sign = 1, start = 0, len = str.length();
long sum = 0;
if (firstChar == '+') {
sign = 1;
start++;
} else if (firstChar == '-') {
sign = -1;
start++;
}
for (int i = start; i < len; i++) {
if (!Character.isDigit(str.charAt(i))){
return (int) sum * sign;
}
sum = sum * 10 + str.charAt(i) - '0';
//超过最大数限制
if (sign == 1 && sum > Integer.MAX_VALUE){
return Integer.MAX_VALUE;
}
//超过最小数限制
if (sign == -1 && (-1) * sum < Integer.MIN_VALUE){
return Integer.MIN_VALUE;
}
}
return (int) sum * sign;
}