一、无重叠区间
每发现有两个的区间重叠了,count++。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a,b)-> {
return Integer.compare(a[0],b[0]);
});
int count = 0;
for(int i = 1;i < intervals.length;i++){
if(intervals[i][0] < intervals[i-1][1]){
intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]);
count++;
}else{
continue;
}
}
return count;
}
}
二、划分字母区间
首先找到每一个字母最远出现在多右边。
然后,从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点。
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> list = new LinkedList<>();
int[] edge = new int[26];
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
edge[chars[i] - 'a'] = i;
}
int right = 0;
int left = -1;
for (int i = 0; i < chars.length; i++) {
right = Math.max(right,edge[chars[i] - 'a']);
if (i == right) {
list.add(i - left);
left = i;
}
}
return list;
}
}
三、合并区间
用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。直接更新res数组里面的区间。
class Solution {
public int[][] merge(int[][] intervals) {
LinkedList<int[]> res = new LinkedList<>();
Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
res.add(intervals[0]);
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] <= res.getLast()[1]) {
int start = res.getLast()[0];
int end = Math.max(intervals[i][1], res.getLast()[1]);
res.removeLast();
res.add(new int[]{start, end});
}
else {
res.add(intervals[i]);
}
}
return res.toArray(new int[res.size()][]);
}
}
四、单调递增的数字
从后往前遍历模拟。
class Solution {
public int monotoneIncreasingDigits(int n) {
char[] ch = String.valueOf(n).toCharArray();
int start = ch.length;
for (int i = ch.length - 1; i > 0; i--) {
if (ch[i] < ch[i - 1]) {
ch[i - 1]--;
start = i;
}
}
for (int i = start; i < ch.length; i++) {
ch[i] = '9';
}
return Integer.parseInt(new String(ch));
}
}
五、监控二叉树
按照注释理解。
class Solution {
int res=0;
public int minCameraCover(TreeNode root) {
// 对根节点的状态做检验,防止根节点是无覆盖状态 .
if(minCame(root)==0){
res++;
}
return res;
}
/**
节点的状态值:
0 表示无覆盖
1 表示有摄像头
2 表示有覆盖
后序遍历,根据左右节点的情况,来判断自己的状态
*/
public int minCame(TreeNode root){
if(root==null){
// 空节点默认为有覆盖状态,避免在叶子节点上放摄像头
return 2;
}
int left=minCame(root.left);
int right=minCame(root.right);
// 如果左右节点都覆盖了的话, 那么本节点的状态就应该是无覆盖,没有摄像头
if(left==2&&right==2){
//(2,2)
return 0;
}else if(left==0||right==0){
// 左右节点都是无覆盖状态,那 根节点此时应该放一个摄像头
// (0,0) (0,1) (0,2) (1,0) (2,0)
// 状态值为 1 摄像头数 ++;
res++;
return 1;
}else{
// 左右节点的 状态为 (1,1) (1,2) (2,1) 也就是左右节点至少存在 1个摄像头,
// 那么本节点就是处于被覆盖状态
return 2;
}
}
}