1. 字符串循环移位包含
[编程之美 3.1](www.cyc2018.xyz/算法/Leetcode 题解/Leetcode 题解 - 字符串.html#)
s1 = AABCD, s2 = CDAA
Return : true
给定两个字符串 s1 和 s2,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。
s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 是否是 s1s1 的子字符串即可。
2. 字符串循环移位
[编程之美 2.17](www.cyc2018.xyz/算法/Leetcode 题解/Leetcode 题解 - 字符串.html#)
s = "abcd123" k = 3
Return "123abcd"
将字符串向右循环移动 k 位。
将 abcd123 中的 abcd 和 123 单独翻转,得到 dcba321,然后对整个字符串进行翻转,得到 123abcd。
3. 字符串中单词的翻转
[程序员代码面试指南](www.cyc2018.xyz/算法/Leetcode 题解/Leetcode 题解 - 字符串.html#)
s = "I am a student"
Return "student a am I"
将每个单词翻转,然后将整个字符串翻转
4. 有效的字母异位词
Leetcode (opens new window)/ 力扣
可以用 HashMap 来映射字符与出现次数,然后比较两个字符串出现的字符数量是否相同。
由于本题的字符串只包含 26 个小写字符,因此可以使用长度为 26 的整型数组对字符串出现的字符进行统计,不再使用 HashMap。
class Solution {
// 哈希表
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
int[] table = new int[26];
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
table[ch - 'a']++;
}
for (int i = 0; i < t.length(); i++) {
char ch = t.charAt(i);
if (--table[ch - 'a'] < 0) {
return false;
}
}
return true;
}
}
5. 最长回文串
Leetcode (opens new window)/ 力扣
class Solution {
public int longestPalindrome(String s) {
int[] counts = new int[128];
for (char ch : s.toCharArray()) {
counts[ch]++;
}
int result = 0;
for (int count : counts) {
result += count / 2 * 2;
if (result % 2 == 0 && count % 2 == 1) {
result++;
}
}
return result;
}
}
6. 同构字符串
Leetcode (opens new window)/ 力扣
解法 1:
class Solution {
// 哈希表
public boolean isIsomorphic(String s, String t) {
// 比较两次,例如 ab 和 cc,从 cc 映射到 ab 不成立
return isMapping(s, t) && isMapping(t, s);
}
public boolean isMapping(String s, String t) {
Map<Character, Character> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char ch1 = s.charAt(i);
char ch2 = t.charAt(i);
if (map.containsKey(ch1) == true) {
if (map.get(ch1) != ch2) {
return false;
}
} else {
map.put(ch1, ch2);
}
}
return true;
}
}
解法 2:
class Solution {
public boolean isIsomorphic(String s, String t) {
int[] map1 = new int[128];
int[] map2 = new int[128];
for (int i = 0; i < s.length(); i++) {
char ch1 = s.charAt(i);
char ch2 = t.charAt(i);
if (map1[ch1] != map2[ch2]) {
return false;
} else {
if (map1[ch1] == 0) {
map1[ch1] = i + 1;
map2[ch2] = i + 1;
}
}
}
return true;
}
}
7. 回文字串 *
Leetcode (opens new window)/ 力扣
class Solution {
public int countSubstrings(String s) {
boolean[][] dp = new boolean[s.length()][s.length()];
int result = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j <= i; j++) {
if (s.charAt(i) == s.charAt(j) && (i - j < 2 || dp[j + 1][i - 1])) {
dp[j][i] = true;
result++;
}
}
}
return result;
}
}
8. 判断一个整数是否是回文数
转换成字符串后进行判断:
class Solution {
public boolean isPalindrome(int x) {
String str = String.valueOf(x);
int i = 0;
int j = str.length() - 1;
while (i < j) {
if (str.charAt(i) != str.charAt(j)) {
return false;
}
i++;
j--;
}
return true;
}
}
进阶:不转换成字符串进行判断‘
要求不能使用额外空间,也就不能将整数转换为字符串进行判断。
将整数分成左右两部分,右边那部分需要转置,然后判断这两部分是否相等。
class Solution {
public boolean isPalindrome(int x) {
// 2 种情况直接返回 false
// 1 负数
// 2 尾数为 0,而且不等于 0,因为 0 不可能是最高位
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
// 反转后半部分进行比较
int reverse = 0;
while (x > reverse) {
reverse = reverse * 10 + x % 10;
x /= 10;
}
return x == reverse || x == reverse / 10;
}
}
9. 计算二进制字串
Leetcode (opens new window)/ 力扣
class Solution {
public int countBinarySubstrings(String s) {
List<Integer> counts = new ArrayList<>();
int n = s.length();
int p = 0;
// 将 0,1 转换成数字(个数)存储到集合中
while (p < n) {
char ch = s.charAt(p);
int count = 0;
while (p < n && s.charAt(p) == ch) {
count++;
p++;
}
counts.add(count);
}
// 进行遍历,求出所有的字串
// 比较相邻,求出两个的最小值
int result = 0;
for (int i = 1; i < counts.size(); i++) {
result += Math.min(counts.get(i), counts.get(i - 1));
}
return result;
}
}
进行优化:
class Solution {
public int countBinarySubstrings(String s) {
int n = s.length();
int p = 0;
int last = 0;
int result = 0;
// 用一个 last 临时变量进行存储
while (p < n) {
char ch = s.charAt(p);
int count = 0;
while (p < n && s.charAt(p) == ch) {
count++;
p++;
}
if (last == 0) {
last = count;
} else {
result += Math.min(last, count);
last = count;
}
}
return result;
}
}