738. 单调递增的数字
Integer.parseInt 方法用于将一个字符串转换为一个整数(int 类型)。
String.valueOf 方法在 Java 中用于将其他类型的数据转换为字符串(String 类型)。
class Solution {
public int monotoneIncreasingDigits(int n) {
String s = String.valueOf(n);
char[] chars = s.toCharArray();
int start = s.length(); // start 记录要从哪个位置开始将其后所有数字修改为9
for(int i = s.length() - 2; i >= 0; i--){
if(chars[i] > chars[i + 1]){
chars[i]--;
start = i + 1;
}
}
for(int i = start; i < s.length(); i++){
chars[i] = '9';
}
return Integer.parseInt(String.valueOf(chars));
}
}
968. 监控二叉树
摄像头可以覆盖上中下三层,如果把摄像头放在叶子节点上,就浪费的一层的覆盖。所以把摄像头放在叶子节点的父节点位置,才能充分利用摄像头的覆盖面积。
所以我们要从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!
此时,大体思路就是从低到上,先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。
class Solution {
int res;
private int traverse(TreeNode curr){
/**
0:该节点无覆盖
1:本节点有摄像头
2:本节点有覆盖
*/
// 空节点,记为有覆盖
if(curr == null)return 2;
int left = traverse(curr.left);
int right = traverse(curr.right);
// 情况1,左右节点都有覆盖
if(left == 2 && right == 2)return 0;
// 情况2
// left == 0 && right == 0 左右节点无覆盖
// left == 1 && right == 0 左节点有摄像头,右节点无覆盖
// left == 0 && right == 1 左节点有无覆盖,右节点摄像头
// left == 0 && right == 2 左节点无覆盖,右节点覆盖
// left == 2 && right == 0 左节点覆盖,右节点无覆盖
if(left == 0 || right == 0){
// 只要左右孩子至少一个无覆盖,父节点应该放摄像头
res++;
return 1;
}
// 情况3
// left == 1 && right == 2 左节点有摄像头,右节点有覆盖
// left == 2 && right == 1 左节点有覆盖,右节点有摄像头
// left == 1 && right == 1 左右节点都有摄像头
if(left ==1 || right == 1)return 2;
// 逻辑不会走到这个 -1 这里
return -1;
}
public int minCameraCover(TreeNode root) {
res = 0;
// 情况4
if(traverse(root) == 0){
// 左右孩子都有覆盖,但根节点无覆盖,单独加一个摄像头
res++;
}
return res;
}
}
146. LRU 缓存
自己多做了一题,和贪心没有关系,是一道模拟过程的题,顺便也记录下来。
class LRUCache {
int capacity;
LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
public LRUCache(int capacity) {
this.capacity = capacity;
}
public int get(int key) {
if(!cache.containsKey(key))return -1;
// 变成常用
makeRecent(key);
return cache.get(key);
}
public void put(int key, int value) {
// 如果本身有key-value,新的value覆盖旧的值
if(cache.containsKey(key)){
// 修改key的值
cache.put(key, value);
// 把key变为常用
makeRecent(key);
return;
}
if(cache.size() >= capacity){
// 链表头部就是最久未使用的 key
int oldestKey = cache.keySet().iterator().next();
cache.remove(oldestKey);
}
// 新的key-value添加到链哈希表尾
cache.put(key, value);
}
private void makeRecent(int key){
int val = cache.get(key);
// 重新添加到队尾
cache.remove(key);
cache.put(key, val);
}
}