文章目录
6055. 转化时间需要的最少操作数
题目描述
解法:贪心+模拟
算法流程:
- 计算出
correct
与current
之间的总时间差,单位:分钟 - 按
60
、15
、5
、1
从大到小的顺序计算增加的次数(借助整除运算)
class Solution {
public int convertTime(String current, String correct) {
if (current == null || correct == null) {
return 0;
}
int res = 0;
int currentHH = Integer.parseInt(current.substring(0, 2));
int correctHH = Integer.parseInt(correct.substring(0, 2));
int currentMM = Integer.parseInt(current.substring(3, 5));
int correctMM = Integer.parseInt(correct.substring(3, 5));
// 总的相差时间,单位:分
int minutes = (correctHH - currentHH) * 60 + correctMM - currentMM;
// 增加60分钟的次数
res += (minutes / 60);
minutes %= 60;
// 增加15分钟的次数
res += (minutes / 15);
minutes = minutes % 15;
// 增加5分钟的次数
res += (minutes / 5);
minutes = minutes % 5;
// 增加1分钟的次数
res += minutes;
return res;
}
}
5235. 找出输掉零场或一场比赛的玩家
题目描述
解法:遍历+哈希表
算法流程:
- 定义一哈希表
map
,key
代表玩家,value
代表输掉的次数(例如:-1
代表输掉1
场,-2
代表输掉2
场),遍历matches
,利用map
统计参与过比赛的玩家的输赢次数 - 遍历
map
,- 若
value=0
,代表该玩家没有输掉任何比赛,放入answer[0]
- 若
value=-1
,代表该玩家恰好输掉了一场比赛,放入answer[1]
- 若
- 按题目要求对
answer[0]
和answer[1]
进行升序排列
class Solution {
public List<List<Integer>> findWinners(int[][] matches) {
Map<Integer, Integer> map = new HashMap<>();
for (int[] match : matches) {
map.put(match[0], map.getOrDefault(match[0], 0) );
// 输掉比赛的次数
map.put(match[1], map.getOrDefault(match[1], 0) - 1);
}
List<Integer> ans0 = new ArrayList<>();
List<Integer> ans1 = new ArrayList<>();
for (int person : map.keySet()) {
if (map.get(person) == 0) {
// 该玩家没有输掉任何比赛
ans0.add(person);
} else if (map.get(person) == -1) {
// 该玩家恰好输掉了一场比赛
ans1.add(person);
}
}
// 排序
Collections.sort(ans0);
Collections.sort(ans1);
List<List<Integer>> res = new ArrayList<>();
res.add(ans0);
res.add(ans1);
return res;
}
}
5219. 每个小孩最多能分到多少糖果
题目描述
二分模板题
算法流程:
-
计算数组
candies
的总和sum
,若 s u m < k sum < k sum<k,直接返回0
-
candies[i]
分堆:代表candies[i]
可以分给多个孩子统计当要给每个孩子分
m
个糖果时,计算出candies
一共可以分够的孩子数量num
,如果可以分的孩子数量num
大于k
,那么就可以增加m
的大小如果这个
m
使用遍历的方式来寻找,那么它的范围是 0 − 1 0 7 0 - 10^7 0−107,时间复杂度太高会导致超时所以考虑使用二分
-
利用二分模板,找满足每个小孩可以拿走的最大糖果数目的最后一个数
// 找小于等于给定数的最后一个数 (满足某个条件的最后一个数) // 判断条件很复杂时用check函数,否则if后直接写条件即可 boolean check(int mid) { // ... return true; } int binarySearch(int left, int right) { while (left < right) { int mid = left + (right - left + 1) / 2; // 右中位数 if (check(mid)) { left = mid; } else { right = mid - 1; } } return left; }
class Solution {
public int maximumCandies(int[] candies, long k) {
if (getCandiesSum(candies) < k) {
return 0;
}
int left = 0, right = 10000000;
while (left < right) {
int mid = left + (right - left + 1) / 2;
if (helper(candies, mid) >= k) {
// 若给每个孩子分配mid个糖果时,全部糖果分配的人数大于等于k,则尝试增加给每个孩子的糖果数
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
private long helper(int[] candies, int mid) {
long res = 0;
for (int candy : candies) {
// 每堆糖果分成任意数量的 子堆
// candy / mid 代表:假设给每个孩子mid个糖果,该堆糖果可以分配给(candy/mid)个小孩
res += (candy / mid);
}
// 最终返回:给每个孩子分配mid个糖果时,全部糖果一共可以分配给多少孩子
return res;
}
private long getCandiesSum(int[] candies) {
long res = 0;
for (int candy : candies) {
res += candy;
}
return res;
}
}
5302. 加密解密字符串
题目描述
逆向思维
对于加密操作encrypt
:
- 首先将
keys
中每个字符和其对应得索引存储在Map
中,便于以O(1)
复杂度找出满足keys[i]==c
的下标i
- 遍历
word1
中的每个字符,借助Map
依次将其替换成values
中的字符串
对于解密操作decrypt
:
- 逆向思考,即加密所有
dictionary
\textit{dictionary}
dictionary 中的字符串。用哈希表记录每个加密后的字符串的出现次数。这样每次调用
decrypt
时,返回哈希表中 word 2 \textit{word}_2 word2 的出现次数即可 - Note: 加密 dictionary \textit{dictionary} dictionary 各个字符串的过程中,需要判断字符是否在 keys \textit{keys} keys 中
class Encrypter {
private String[] values;
private Map<Character, Integer> keysMap;
private Map<String, Integer> cnt;
public Encrypter(char[] keys, String[] values, String[] dictionary) {
this.values = values;
this.keysMap = new HashMap<>();
this.cnt = new HashMap<>();
for (int i = 0; i < keys.length; i++) {
keysMap.put(keys[i], i);
}
for (String s : dictionary) {
String e = encrypt(s);
cnt.put(e, cnt.getOrDefault(e, 0) + 1);
}
}
public String encrypt(String word1) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word1.length(); i++) {
if (!keysMap.containsKey(word1.charAt(i))) {
return "";
}
int idx = keysMap.get(word1.charAt(i));
sb.append(values[idx]);
}
return sb.toString();
}
public int decrypt(String word2) {
return cnt.getOrDefault(word2, 0);
}
}
/**
* Your Encrypter object will be instantiated and called as such:
* Encrypter obj = new Encrypter(keys, values, dictionary);
* String param_1 = obj.encrypt(word1);
* int param_2 = obj.decrypt(word2);
*/