Learn && Live
虚度年华浮萍于世,勤学善思至死不渝
前言
Hey,欢迎来到Connor的算法练习室,这个系列记录了我的算法练习过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/G2nnQ,话不多说我们马上开始!
剑指 Offer II 032.有效的变位词⭐️
给定两个字符串 s 和 t ,编写一个函数来判断它们是不是一组变位词(字母异位词)。
注意:若 s 和 t 中每个字符出现的次数都相同且字符顺序不完全相同,则称 s 和 t 互为变位词(字母异位词)。
示例1:
输入: s = "anagram", t = "nagaram"
输出: true
示例2:
输入: s = "rat", t = "car"
输出: false
示例3:
输入: s = "a", t = "a"
输出: false
提示:
-
1 <= s.length, t.length <= 5 * 104
-
s
andt
仅包含小写字母
解题思路:
由题意,变位词要求(1)每个字符出现的次数相同;(2)字符顺序不完全相同,即除两个字符串完全相同,其他皆可。
可推出条件:字符串不相等,但排序后的字符串(字符数组)完全相同
class Solution {
public boolean isAnagram(String s, String t) {
if(s.length() != t.length() || s.equals(t)) {
return false;
}
char[] ss = s.toCharArray();
char[] ts = t.toCharArray();
Arrays.sort(ss);
Arrays.sort(ts);
// 注意Arrays方法的使用
return Arrays.equals(ss, ts);
}
}
剑指 Offer II 033. 变位词组⭐️⭐️
给定一个字符串数组 strs
,将 变位词 组合在一起。 可以按任意顺序返回结果列表。
**注意:**若两个字符串中每个字符出现的次数都相同,则称它们互为变位词。
示例1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例2:
输入: strs = [""]
输出: [[""]]
示例3:
输入: strs = ["a"]
输出: [["a"]]
提示:
-
1 <= strs.length <= 104
-
0 <= strs[i].length <= 100
-
strs[i]
仅包含小写字母
解题思路:
判定变位词的思路与前一题相同,主要讨论如何实现分组
(1)首先维护一个HashMap,key保存每个字符串排序后的字符串(这很好想到,毕竟只要出现次数相同就行),value保存对应的分组
(2)将排序后的char[]数组转换为字符串,将这个字符串作为key来查找,得到相应的List<String>
(3)将当前的字符串加入到List中,并更新map
注意:第(2)步的转换需要注意使用正确的转换方法:(1)new String(char[]);(2)String.valueOf(char[]),千万不要使用array.toString(),把它的源码翻出来就知道为什么了
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for(String str : strs) {
char[] array = str.toCharArray();
Arrays.sort(array);
String key = new String(array);
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}
}
剑指 Offer II 035. 最小时间差⭐️⭐️
给定一个 24 小时制(小时:分钟 “HH:MM”)的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。
示例1:
输入:timePoints = ["23:59","00:00"]
输出:1
示例2:
输入:timePoints = ["00:00","23:59","00:00"]
输出:0
提示:
2 <= timePoints <= 2 * 104
timePoints[i]
格式为 “HH:MM”
解题思路:
将 timePoints 排序后,最小时间差必然出现在 timePoints 的两个相邻时间,或者 timePoints 的两个首尾时间中。因此排序后遍历一遍 timePoints 即可得到最小时间差。
class Solution {
public int findMinDifference(List<String> timePoints) {
Collections.sort(timePoints);
int ans = Integer.MAX_VALUE;
int t0Minutes = getMinutes(timePoints.get(0));
int preMinutes = t0Minutes;
for (int i = 1; i < timePoints.size(); ++i) {
int minutes = getMinutes(timePoints.get(i));
// 相邻时间的时间差
ans = Math.min(ans, minutes - preMinutes);
preMinutes = minutes;
}
// 首尾时间的时间差
ans = Math.min(ans, t0Minutes + 1440 - preMinutes);
return ans;
}
public int getMinutes(String t) {
return ((t.charAt(0) - '0') * 10 + (t.charAt(1) - '0')) * 60 + (t.charAt(3) - '0') * 10 + (t.charAt(4) - '0');
}
}