1.最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
题解思路:
首先遍历数组,取到长度最短字符串作为比较基准。再次遍历数组对字符串元素进行与基准字符串等长截取,并比较字符串是否相同,如不相同截掉基准字符串的最后一个字符继续比较,直至取到公共前缀(空字符串)返回。
此题可采用暴力破解方式,但耗时更长,内存消耗更多。
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) return "";
String result = "";
int minLength = Integer.MAX_VALUE;
for (String str : strs) {
if (str.length() < minLength) {
minLength = str.length();
result = str;
}
}
for (String str : strs) {
while (!str.substring(0, minLength).equals(result)) {
result = result.substring(0, --minLength);
}
}
return result;
}
2.最长回文子串
给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
题解思路:
动态规划方式:
/*
动态规划方式:最长回文字符串
*/
public static String longestPalindrome(String s) {
// 特判
if (s.length() == 0 || s.length() == 1) return s;
int length = s.length();
// 用来记录字符串长度内,任意两个索引范围内的字符是否是回文字符串
boolean[][] em = new boolean[length][length];
String result = "";
for (int l = 0; l < length; l++) {// 循环截取不同长度字符串进行验证,l为j-i角标的差值
for (int i = 0; i + l < length; i++) {// 截取的字符串验证两端(i,j)字符是否相同
int j = i + l;
if (l == 0) {// 截取的只有一个字符,最长回文就是当前一个字符
em[i][j] = true;
} else if (l == 1) {// 截取只有两个字符,判断两个字符是否相同
em[i][j] = (s.charAt(i) == s.charAt(j));
} else {// 截取字符数>2时,判断i j字符是否相等的同时,会取到之前判断过的i+1,j-1位置上的字符是否相同
em[i][j] = (s.charAt(i) == s.charAt(j) && em[i + 1][j - 1]);
}
// 当前两个索引范围的字符串是回文的,并且用result记录长度更长的一个
if (em[i][j] && l + 1 > result.length()) {
result = s.substring(i, i + l + 1);
}
}
}
return result;
}
3.翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词。
题解思路:
调用splite()方法分割为String[],再倒叙拼接为字符串,并在拼接每个单词后拼接空格,最后trim一下。
public String reverseWords(String s) {
StringBuilder sb = new StringBuilder();
String[] words = s.split(" ");
for (int i = words.length - 1; i >= 0; i--) {
sb.append(words[i]);
if (words[i].length() > 0 && i != 0)
sb.append(" ");
}
return sb.toString().trim();
}
4.反转字符串(双指针方式)
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
题解思路:
利用双指针(两端反向)分别从头和尾循环进行元素互换,直到两个指针相遇或头大于尾指针。
public void reverseString(char[] s) {
for (int i = 0; i < (s.length + 1) / 2; i++) {
int j = s.length - i - 1;
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
5.反转字符串中的单词 III(双指针)
给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
题解思路:
采用双指针解法,定义双指针(同向快慢)fast、slow,fast先指针向后遍历字符数组当遇到空格时,记录空格的下一位next并从空格的前一位与slow进行循环互换元素。互换完毕后将slow与fast同时指向所记录的next的位置上,fast继续向后遍历与反转调换。
public String reverseWords(String s) {
char[] chars = s.toCharArray();
int fast = 0, slow = 0;
int length = chars.length;
while (fast < length) {
while (fast < length && chars[fast] != ' ') {
fast++;
}
// 记录下一个单词开始字符角标
int next = fast + 1;
fast--;
// 循环翻转单词字符串
while (fast > slow) {
// 互换两者位置
char temp = chars[slow];
chars[slow] = chars[fast];
chars[fast] = temp;
fast--;
slow++;
}
fast = next;
slow = next;
}
return new String(chars);
}