字符串反转

反转字符串

image-20221031220434007
1
2
3
4
5
6
7
8
9
10
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while (left < right) {
Character temp;
temp = s[left];
s[left++] = s[right];
s[right--] = temp;
}
}

字符串中的第一个唯一字符

image-20221031223017748
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 暴力方法,超时
public int firstUniqChar(String s) {
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
for (int i = 0; i < s.toCharArray().length; i++) {
if (map.get(s.charAt(i)) == 1) {
return i;
}
}
return -1;
}

将长度为26的数组作为哈希表

1
2
3
4
5
6
7
8
9
10
11
12
public int firstUniqChar(String s) {
int[] nums = new int[26];
for (char ch : s.toCharArray()) {
nums[ch - 'a']++;
}
for (char ch : s.toCharArray()) {
if (nums[ch - 'a'] == 1){
return s.indexOf(ch);
}
}
return -1;
}

反转字符串 II

image-20221031223102817
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
for (int l = 0; l < chars.length; l += 2 * k) {
reverse(chars, l, Math.min(l + k, chars.length) - 1);
}
return String.valueOf(chars);
}
void reverse(char[] chars, int l, int r) {
while (l < r) {
char c = chars[l];
chars[l++] = chars[r];
chars[r--] = c;
}
}

字符串的统计

找不同

image-20221031225439375
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public char findTheDifference(String s, String t) {
int[] nums = new int[26];
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
nums[ch - 'a']++;
}
for (int i = 0; i < t.length(); i++) {
char ch = t.charAt(i);
nums[ch - 'a']--;
if (nums[ch - 'a'] < 0){
return ch;
}
}
return ' ';
}

根据字符出现频率排序

image-20221101200140032
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public String frequencySort(String s) {
HashMap<Character, Integer> map = new HashMap<>();
int length = s.length();
for (int i = 0; i < length; i++) {
char ch = s.charAt(i);
int frequency = map.getOrDefault(ch, 0) + 1;
map.put(ch, frequency);
}
ArrayList<Character> list = new ArrayList<>(map.keySet());
Collections.sort(list, (a, b) -> map.get(b) - map.get(a));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
char ch = list.get(i);
int count = map.get(ch);
for (int j = 0; j < count; j++) {
sb.append(ch);
}
}
return sb.toString();
}

机器人能否返回原点

image-20221101201307158
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public boolean judgeCircle(String moves) {
char[] chars = moves.toCharArray();
int UpAndDown = 0;
int LeftAndRight = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 'R'){
LeftAndRight++;
}else if (chars[i] == 'L'){
LeftAndRight--;
}else if (chars[i] == 'U'){
UpAndDown++;
}else {
UpAndDown--;
}
}
return UpAndDown == 0 && LeftAndRight == 0;
}

学生出勤记录 I

image-20221101202716403
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public boolean checkRecord(String s) {
char[] chars = s.toCharArray();
int absent = 0;
int temp = 0;
int max = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 'A'){
absent++;
temp = 0;
}else if(chars[i] == 'L'){
temp++;
}else if(chars[i] == 'P'){
temp = 0;
}
max = Math.max(max,temp);
}
return absent < 2 && max < 3;
}

计数二进制子串

image-20221101210631493
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public int countBinarySubstrings(String s) {
/**
* {2,2,2,2}
* {2,2} {2,2} {2,2}
* {1,1} {1,1} {1,1}
*
* {1,1,1,1,1}
* {1,1} {1,1} {1,1} {1,1} {1,1}
*/
char[] chars = s.toCharArray();
List<Integer> counts = new ArrayList<>();
int left = 0;
int res = 0;
while (left < chars.length) {
char ch = chars[left];
int count = 0;
while (left < chars.length && chars[left] == ch) {
++left;++count;
}
counts.add(count);
}
for (int i = 1; i < counts.size(); i++) {
res += Math.min(counts.get(i), counts.get(i-1));
}
return res;
}

题目中计算具有相同数量0和1的非空(连续)子字符串,其实这里的“相同数量”说的不是“子串”与“子串”之间的,而是 0和1 之间的

  • “1100”有2个0,2个1(0和1相同数量)

  • “10”有1个0,1个1(0和1相同数量)

那么只需要找到0和1相间位置处,左右0和1的数量的最小值,该值就是能组成的子串的个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public int countBinarySubstrings(String s) {
/**
* lastCount: 代表上一个区域的 0/1 的个数
* curCount: 代表当前区域的 0/1 的个数
*/
int i = 0, len = s.length(), lastCount = 0, res = 0;
while (i < len) {
int curCount = 0;
char curChar = s.charAt(i);
while (i < len && s.charAt(i) == curChar) {
++curCount;
++i;
}
res += Math.min(lastCount, curCount);
// 更新lastCount
lastCount = curCount;
}
return res;
}