循环移位可以通过部分翻转然后整体翻转来完成
字符串循环移位包含
给定两个字符串 s1 和 s2,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。
s1 = AABCD, s2 = CDAA
Return : true
s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 是否是 s1s1 的子字符串即可。
字符串循环移位
将字符串向右循环移动 k 位。
s = “abcd123” k = 3
Return “123abcd”
将 abcd123 中的 abcd 和 123 单独翻转,得到 dcba321,然后对整个字符串进行翻转,得到 123abcd。
字符串中单词的翻转
s = “I am a student”
Return “student a am I”
将每个单词翻转,然后将整个字符串翻转。
leetcode 242 有效的字母异位词(简单)
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
说明:
你可以假设字符串只包含小写字母。
题解:
常规词频统计
class Solution {
public boolean isAnagram(String s, String t) {
int n = s.length();
int m = t.length();
if(n != m){
return false;
}
int[] freqS = new int[26];
int[] freqT = new int[26];
for(int i=0; i
leetcode 409 最长回文串(简单)
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如 “Aa” 不能当做一个回文字符串。
注意:
假设字符串的长度不会超过 1010。
示例 1:
输入:“abccccdd”
输出:7
解释:我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
题解:
class Solution {
public int longestPalindrome(String s) {
int res = 0;
// 词频统计
int[] freq = new int[256];
for(char c: s.toCharArray()){
freq[c]++;
}
for(int i: freq){
i = i/2*2; // 向下取偶
res+=i;
}
if(res
记录一个字符上次出现的位置,如果两个字符串中的字符上次出现的位置一样,那么就属于同构。
leetcode 205 同构字符串(简单)
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1:
输入: s = “egg”, t = “add”
输出: true
示例 2:
输入: s = “foo”, t = “bar”
输出: false
示例 3:
输入: s = “paper”, t = “title”
输出: true
说明:
你可以假设 s 和 t 具有相同的长度。
题解:
使用一个hashmap记录
class Solution {
public boolean isIsomorphic(String s, String t) {
if(s.length() != t.length()){
return false;
}
HashMap map = new HashMap<>();
for(int i=0; i
使用两个数组分别记录当前字符上次出现的位置
class Solution {
public boolean isIsomorphic(String s, String t) {
if(s.length() != t.length()){
return false;
}
int n = s.length();
// 分别记录当前字符上次出现的位置, 等于0时表示第一次出现
int[] sLastIndexOf = new int[256];
int[] tLastIndexOf = new int[256];
for(int i=0; i
leetcode 647 回文子串(中等)
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
示例 1:
输入: “abc”
输出: 3
解释: 三个回文子串: “a”, “b”, “c”.
示例 2:
输入: “aaa”
输出: 6
说明: 6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”.
注意:
题解:
从字符串的某一位开始,尝试向两边去扩展子字符串
class Solution {
private int res;
public int countSubstrings(String s) {
for(int i=0; i=0 && end
动态规划, 相比于上述解法,时间性能差了许多
class Solution {
public int countSubstrings(String s) {
int res = 0;
int n = s.length();
// dp[i][j] 表示[i,j]的字符是否为回文子串
boolean[][] dp = new boolean[n][n];
// 注意,外层循环要倒着写,内层循环要正着写
// 因为要求dp[i][j] 需要知道dp[i+1][j-1]
for(int i=n-1; i>=0; i--){
for(int j=i; j
leetcode 9 回文数(简单)
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
题解:
要求不能使用额外空间,也就不能将整数转换为字符串进行判断。
将整数分成左右两部分,右边那部分需要转置,然后判断这两部分是否相等。
class Solution {
public boolean isPalindrome(int x) {
if(x==0){
return true;
}
if(x<0 || x%10 == 0){
return false;
}
int right = 0;
while(x>right){
right = right*10+x%10;
x = x/10;
}
return x==right || x==right/10;
}
}
leetcode 696 计数二进制子串(简单)
给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。
示例 1 :
输入: “00110011”
输出: 6
解释: 有6个子串具有相同数量的连续1和0:“0011”,“01”,“1100”,“10”,“0011” 和 “01”。
请注意,一些重复出现的子串要计算它们出现的次数。
另外,“00110011”不是有效的子串,因为所有的0(和1)没有组合在一起。
示例 2 :
输入: “10101”
输出: 4
解释: 有4个子串:“10”,“01”,“10”,“01”,它们具有相同数量的连续1和0。
注意:
题解:
class Solution {
public int countBinarySubstrings(String s) {
int res = 0;
int lastLen = 0; // 记录之前的连续相同的字符的长度
int curLen = 1; // 记录当前连续相同的字符的长度
for(int i=1; i
参考:Cyc2018 算法