242 有效的字母异位词
题目描述:
给定两个字符串s和t,编写一个函数来判断t是不是s的字母异位词。也就是判断两个字符串包含的字符是否完全相同。
示例:
输入: s = "anagram", t = "nagaram"
输出: true
输入: s = "rat", t = "car"
输出: false
说明: 你可以假设字符串只包含小写字母。
题解:
- 首先判断两个字符串长度是否相等,不相等则直接返回 false;
- 然后我们new一个
HashMap<Character,Integer>,用来存储字符及对应的次数; - 将字符串s放入map中,同时记录字符出现次数cnt;
- 遍历字符串t中的字符,若map无,直接返回false;
- 若有,先判断对应cnt是否大于0,是,则对应cnt-1,否,则直接返回false;
- 如果cnt<0,就返回false;
- 结束。
代码:
import java.util.HashMap;
import java.util.Map;
/*
* @lc app=leetcode.cn id=242 lang=java
*
* [242] 有效的字母异位词
*/
// @lc code=start
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
//new hashmap
Map<Character,Integer> sMap = new HashMap<>();
// 遍历s字符串
for (char c : s.toCharArray()) {
sMap.put(c, sMap.getOrDefault(c, 0) + 1);
}
/*
for (char c : t.toCharArray()) {
sMap.put(c, sMap.getOrDefault(c, 0) - 1);
if (sMap.get(c) < 0) {
return false;
}
}*/
// 遍历t字符串
for (char c : t.toCharArray()) {
if (sMap.containsKey(c) && sMap.get(c) > 0) {
sMap.put(c, sMap.get(c) - 1);
}else{
return false;
}
}
return true;
}
}
// @lc code=end
205同构字符串
题目描述:
给定两个字符串 s 和t,判断它们是否是同构的。
如果 s 中的字符可以按某种映射关系替换得到 t,那么这两个字符串是同构的。
每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
示例:
输入:s = "egg", t = "add"
输出:true
输入:s = "foo", t = "bar"
输出:false
输入:s = "paper", t = "title"
输出:true
可以假设s和 t长度相同。
题解:
我们判断 s和 t 每个位置上的字符是否都一一对应,即 s 的任意一个字符被 t 中唯一的字符对应,同时 t 的任意一个字符被 s 中唯一的字符对应。这也被称为「双射」的关系。
以示例 s = "foo", t = "bar"为例,t 中的字符 a 和 r 虽然有唯一的映射 o,但对于 s 中的字符 o 来说其存在两个映射 {a,r},故不满足条件。
因此,我们维护两张哈希表,第一张哈希表 s2t 以 s 中字符为键,映射至 t 的字符为值,第二张哈希表 t2s 以 t 中字符为键,映射至 s 的字符为值。从左至右遍历两个字符串的字符,不断更新两张哈希表,如果出现冲突(即当前下标 index 对应的字符 s[index] 已经存在映射且不为 t[index], 或当前下标 index 对应的字符 t[index] 已经存在映射且不为s[index])时说明两个字符串无法构成同构,返回 false。
如果遍历结束没有出现冲突,则表明两个字符串是同构的,返回 true 即可。
代码:
import java.util.HashMap;
import java.util.Map;
/*
* @lc app=leetcode.cn id=205 lang=java
*
* [205] 同构字符串
*/
// @lc code=start
class Solution {
public boolean isIsomorphic(String s, String t) {
//定义两个哈希表
Map<Character,Character> s2t = new HashMap<>();
Map<Character,Character> t2s = new HashMap<>();
int size = s.length();
//遍历字符串
for (int i = 0; i < size; i++) {
char a = s.charAt(i);//s中字符
char b = t.charAt(i);//t中字符
//当前下标 i 对应的字符 s[i] 已经存在映射且不为 t[i]
if (s2t.containsKey(a) && s2t.get(a) != b) {
return false;
}
//当前下标 i 对应的字符 t[i] 已经存在映射且不为s[i]
if (t2s.containsKey(b) && t2s.get(b) !=a ) {
return false;
}
s2t.put(a, b);
t2s.put(b, a);
}
return true;
}
}
// @lc code=end
647回文子串
题目描述:
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例:
输入:"abc"
输出:3
解释:三个回文子串: "a", "b", "c"
输入:"aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
题解:
把字符串中的 一个或者相邻两个字符 当作中心,然后通过两个指针 分别向左向右 扩展,并在扩展的过程中记录当前时刻是否具有 回文属性。
代码:
/*
* @lc app=leetcode.cn id=647 lang=java
*
* [647] 回文子串
*/
// @lc code=start
class Solution {
public int countSubstrings(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
count += extendSubstrings(s, i, i);//偶数
count += extendSubstrings(s, i, i+1);//奇数
}
return count;
}
public static int extendSubstrings(String s,int left,int right){
int count = 0;
while (left >= 0 && right <s.length() && s.charAt(left) == s.charAt(right)) {
--left;
++right;
++count;
}
return count;
}
}
// @lc code=end
696计数二进制子串
题目描述:
给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。
示例:
输入: "00110011"
输出: 6
解释: 有6个子串具有相同数量的连续1和0: “0011”,“01”,“1100”,“10”,“0011” 和 “01”。
请注意,一些重复出现的子串要计算它们出现的次数。
另外,“00110011”不是有效的子串,因为所有的0(和1)没有组合在一起。
输入: "10101"
输出: 4
解释: 有4个子串:“10”,“01”,“10”,“01”,它们具有相同数量的连续1和0。
题解:
-
官方题解:
我们可以将字符串 s 按照 0 和 1 的连续段分组,存在counts 数组中,例如 s=00111011,可以得到这样的counts 数组:counts={2,3,1,2}。
这里counts 数组中两个相邻的数一定代表的是两种不同的字符。假设 counts 数组中两个相邻的数字为 u 或者 v,它们对应着 u 个 0 和 v 个 1,或者 u 个 1 和 v 个 0。它们能组成的满足条件的子串数目为 min{u,v},即一对相邻的数字对答案的贡献。
我们只要遍历所有相邻的数对,求它们的贡献总和,即可得到答案。
-
类似回文子串解法:
代码:
-
官方解答代码:
class Solution { public int countBinarySubstrings(String s) { List<Integer> counts = new ArrayList<Integer>(); int ptr = 0, n = s.length(); while (ptr < n) { char c = s.charAt(ptr); int count = 0; while (ptr < n && s.charAt(ptr) == c) { ++ptr; ++count; } counts.add(count); } int ans = 0; for (int i = 1; i < counts.size(); ++i) { ans += Math.min(counts.get(i), counts.get(i - 1)); } return ans; } } -
类似回文解法
class Solution { public int countBinarySubstrings(String s) { int result = 0; char[] chars = s.toCharArray(); for(int i = 1; i < s.length(); i++){ int left = i - 1, right = i; char leftChar = chars[left]; char rightChar = chars[right]; if(leftChar == rightChar) continue; while(left >= 0 && right < s.length() && chars[left] == leftChar && chars[right] == rightChar){ left--; right++; result++; } } return result; } }