344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

思路一:

从中间开始向两边遍历,然后两边交换位置,最终获得字符串的反转

1
2
3
4
5
6
7
8
9
10
11
12
//
class Solution {
public void reverseString(char[] s) {
int len = s.length,size = len;
for(int i = 0;i < len/2;i++){
size--;
char tmp = s[i];
s[i] = s[size];
s[size] = tmp;
}
}
}

思路二:

使用位运算,每次异或进行赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public void reverseString(char[] s) {
int l = 0;
int r = s.length - 1;
while (l < r) {
s[l] ^= s[r]; //构造 a ^ b 的结果,并放在 a 中
s[r] ^= s[l]; //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
s[l] ^= s[r]; //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
l++;
r--;
}
}
}

541. 反转字符串 II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

思路:
参考上面题目,其实思路差不多每次反抓2k字符里面的前k个,如果最后的字符少于k,则直接全部反转.

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//解法一
class Solution {
public String reverseStr(String s, int k) {
StringBuffer res = new StringBuffer();
int length = s.length();
int start = 0;
while (start < length) {
// 找到k处和2k处
StringBuffer temp = new StringBuffer();
// 与length进行判断,如果大于length了,那就将其置为length
int firstK = (start + k > length) ? length : start + k;
int secondK = (start + (2 * k) > length) ? length : start + (2 * k);

//无论start所处位置,至少会反转一次
temp.append(s.substring(start, firstK));
res.append(temp.reverse());

// 如果firstK到secondK之间有元素,这些元素直接放入res里即可。
if (firstK < secondK) { //此时剩余长度一定大于k。
res.append(s.substring(firstK, secondK));
}
start += (2 * k);
}
return res.toString();
}
}

//方法二
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i = 0; i < ch.length; i += 2 * k){
int start = i;
//这里是判断尾数够不够k个来取决end指针的位置
int end = Math.min(ch.length - 1, start + k - 1);
//用异或运算反转
while(start < end){
ch[start] ^= ch[end];
ch[end] ^= ch[start];
ch[start] ^= ch[end];
start++;
end--;
}
}
return new String(ch);
}
}

//方法三
class Solution {
public String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i+=2*k) {
if(i+k<=chars.length){
reverse(chars,i,i+k-1);
continue;
}
reverse(chars,i,chars.length-1);

}
return new String(chars);

}
public void reverse(char[] chars,int i,int j){
for (;i<j;i++,j--) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
}
}

7. 整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

思路:
可以直接存一个临时的翻转结果,如果这个翻转结果除以10不等于上一个结果,说明有溢出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int reverse(int x) {
int res=0;
while(x!=0){
int temp=res*10+x%10;
x=x/10;
if(temp/10!=res){
return 0;
}
res=temp;
}
return res;
}
}

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

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

思路:
定义一个大小26的字符数组,依此遍历字符串的每一个字符,遇到对应的就对对应的字符数组的数字加1,然后再次循环遍历,如果该值等于1,便返回该数组索引,否则返回-1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public int firstUniqChar(String s) {
int[] freq = new int[26];
char[] chars = s.toCharArray();
for (char ch : chars) {
freq[ch - 'a']++;
}
for (int i = 0; i < chars.length; i++) {
if (freq[chars[i] - 'a'] == 1) {
return i;
}
}
return -1;
}
}

剑指 Offer II 032. 有效的变位词

给定两个字符串 s 和 t ,编写一个函数来判断它们是不是一组变位词(字母异位词)。
注意:若 s 和 t 中每个字符出现的次数都相同且字符顺序不完全相同,则称 s 和 t 互为变位词(字母异位词)

思路:

先定义一个大小26的数组,遍历第一个字符串的每一个字符,然后统计对应26个字符的出现的次数,然后对第二个字符串进行遍历,遇到了就减一,最后遍历该数组,如果每一个值都是0,则是有效的,否则不是.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public boolean isAnagram(String s, String t) {
int[] record = new int[26];

for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++;
}

for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}

for (int count: record) {
if (count != 0) {
return false;
}
}
return true;
}
}

125. 验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

思路:
调用api方法把字符串转换成小写的,然后创建一个StringBuilder,如果遇到数字和字符,便加进去,最后比较该字符和反转后的字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public boolean isPalindrome(String s) {
if (s == null) return true;
s = s.toLowerCase();
int l = s.length();
StringBuilder str = new StringBuilder(l);
for (char c : s.toCharArray()) {
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')) {
str.append(c);
}
}
return str.toString().equals(str.reverse().toString());
}
}