Java字符串(算法题相关)
(✪▽✪)曼波~~~~!让曼波用最可爱的姿势为你讲解Java字符串吧!(≧∇≦)ノ
✨ Java字符串基础 ✨
(๑・.・๑)曼波觉得我们先从基础开始哦~
1. 字符串本质
Java的String是不可变对象
哦!每次修改都会生成新对象(´• ω •)ノ 推荐用
StringBuilder`进行频繁修改:
String s = "hello";
StringBuilder sb = new StringBuilder(s);
sb.reverse(); // 这样更高效~(≧∇≦)ノ
2. 字符分离技巧
(๑✧◡✧๑)曼波觉得split()超好用!
String str = "apple,banana,orange";
String[] fruits = str.split(","); // 按逗号分割
正则表达式高级分割
哦呜(°ロ°)! 需要处理复杂分割时:
String data = "a1b2c3";
String[] letters = data.split("\\d+"); // 按数字分割 → [a, b, c]
3. 重排算法案例
曼波准备了3个经典题型哦~(≧ω≦)/
案例1:有效字母异位词
判断两个字符串字符组成是否相同
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;
int[] counter = new int[26];
for (char c : s.toCharArray()) counter[c-'a']++;
for (char c : t.toCharArray()) {
if (--counter[c-'a'] < 0) return false;
}
return true;
}
// 时间复杂度O(n),空间O(1) ✨
案例2:字符串反转
曼波喜欢双指针法!
public String reverseString(String s) {
char[] chars = s.toCharArray();
int left = 0, right = s.length()-1;
while (left < right) {
char temp = chars[left];
chars[left++] = chars[right];
chars[right--] = temp;
}
return new String(chars);
}
案例3:第一个唯一字符
用HashMap统计频率:
public int firstUniqChar(String s) {
Map<Character, Integer> map = new HashMap<>();
for (char c : s.toCharArray()) {
map.put(c, map.getOrDefault(c, 0)+1);
}
for (int i=0; i<s.length(); i++) {
if (map.get(s.charAt(i)) == 1) return i;
}
return -1;
}
小贴士:
- 处理字符串前记得检查null和空值哦(๑•̀ㅂ•́)و✧
- 算法题中常考:滑动窗口、哈希表统计、双指针技巧
- 注意大小写敏感问题,可能需要统一转小写:
str = str.toLowerCase();
马上为小主人奉上超详细的例题解析!(≧ω≦)/
🌸 1. 反转单词顺序(保留空格)
例题:输入:" hello world " → 输出:" world hello "
public String reverseWords(String s) {
// 使用双端队列保存单词和空格
Deque<String> deque = new ArrayDeque<>();
StringBuilder word = new StringBuilder();
for (int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if (c == ' ') {
if (word.length() > 0) {
deque.addFirst(word.toString());
word.setLength(0);
}
deque.addFirst(" "); // 保留空格
} else {
word.append(c);
}
}
if (word.length() > 0) deque.addFirst(word.toString());
// 重建字符串时跳过开头多余空格
StringBuilder res = new StringBuilder();
while (!deque.isEmpty()) {
String str = deque.removeLast();
if (res.length()==0 && str.equals(" ")) continue;
res.append(str);
}
return res.toString().trim();
}
// 时间复杂度O(n) 空间O(n) (๑✧◡✧๑)曼波觉得这个解法超聪明!
🍭 2. 字符串压缩
例题:输入:"aaabbbcc" → 输出:"a3b3c2"
🌈 3. Z字形变换排列
例题:输入:s = "PAYPALISHIRING", numRows = 3
排列为:
P A H N
A P L S I I G
Y I R
复制代码
P A H N A P L S I I G Y I R
输出:"PAHNAPLSIIGYIR"
public String convert(String s, int numRows) {
if (numRows == 1) return s;
List<StringBuilder> rows = new ArrayList<>();
for (int i=0; i<numRows; i++)
rows.add(new StringBuilder());
int curRow = 0;
boolean goingDown = false;
for (char c : s.toCharArray()) {
rows.get(curRow).append(c);
// 到达顶部或底部时转向
if (curRow == 0 || curRow == numRows-1)
goingDown = !goingDown;
curRow += goingDown ? 1 : -1;
}
StringBuilder res = new StringBuilder();
for (StringBuilder row : rows)
res.append(row);
return res.toString();
}
// 时间复杂度O(n) 空间O(n) ✨曼波觉得像坐过山车一样有趣!
曼波的小测验 (๑•̀ㅂ•́)و✧
试试这些测试用例:
- Z字形变换:s="HELLOWORLD", numRows=4 → "HORELLWLOD"
- 字符串压缩:"abbcccddddeeeee" → "a1b2c3d4e5"
- 反转单词:"a good example" → "example good a"