题目1:
5234. 移除字母异位词后的结果数组
显示英文描述
- 通过的用户数0
- 尝试过的用户数0
- 用户总通过次数0
- 用户总提交次数0
- 题目难度Easy
给你一个下标从 0 开始的字符串 words ,其中 words[i] 由小写英文字符组成。
在一步操作中,需要选出任一下标 i ,从 words 中 删除 words[i] 。其中下标 i 需要同时满足下述两个条件:
0 < i < words.lengthwords[i - 1]和words[i]是 字母异位词 。
只要可以选出满足条件的下标,就一直执行这个操作。
在执行所有操作后,返回 words 。可以证明,按任意顺序为每步操作选择下标都会得到相同的结果。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。例如,"dacb" 是 "abdc" 的一个字母异位词。
示例 1:
输入: words = ["abba","baba","bbaa","cd","cd"]
输出: ["abba","cd"]
解释:
获取结果数组的方法之一是执行下述步骤:
- 由于 words[2] = "bbaa" 和 words[1] = "baba" 是字母异位词,选择下标 2 并删除 words[2] 。
现在 words = ["abba","baba","cd","cd"] 。
- 由于 words[1] = "baba" 和 words[0] = "abba" 是字母异位词,选择下标 1 并删除 words[1] 。
现在 words = ["abba","cd","cd"] 。
- 由于 words[2] = "cd" 和 words[1] = "cd" 是字母异位词,选择下标 2 并删除 words[2] 。
现在 words = ["abba","cd"] 。
无法再执行任何操作,所以 ["abba","cd"] 是最终答案。
示例 2:
输入: words = ["a","b","c","d","e"]
输出: ["a","b","c","d","e"]
解释:
words 中不存在互为字母异位词的两个相邻字符串,所以无需执行任何操作。
提示:
1 <= words.length <= 1001 <= words[i].length <= 10words[i]由小写英文字母组成
解法:
class Solution {
/*
根据题意模拟,遍历数组,如果当前元素和前一个元素是异或word,则删除当前元素
判断2个word是否是异或work,先转成char数组,排序,再转字符串,equal比较
*/
public List<String> removeAnagrams(String[] words) {
List<String> list = Arrays.stream(words).collect(Collectors.toList());
for (int i = 1; i < list.size(); i++) {
if (isOrWord(list.get(i), list.get(i - 1))) {
System.out.println(i);
list.remove(i);
i--;
}
}
return list;
}
boolean isOrWord(String s1, String s2) {
char[] s1Char = s1.toCharArray();
Arrays.sort(s1Char);
char[] s2Char = s2.toCharArray();
Arrays.sort(s2Char);
// System.out.println(s1Char);
// System.out.println(s2Char);
// System.out.println(Arrays.toString(s1Char).equals(Arrays.toString(s2Char)));
return Arrays.toString(s1Char).equals(Arrays.toString(s2Char));
}
}
题目2
6064. 不含特殊楼层的最大连续楼层数
显示英文描述
- 通过的用户数4952
- 尝试过的用户数5295
- 用户总通过次数4997
- 用户总提交次数9299
- 题目难度Medium
Alice 管理着一家公司,并租用大楼的部分楼层作为办公空间。Alice 决定将一些楼层作为 特殊楼层 ,仅用于放松。
给你两个整数 bottom 和 top ,表示 Alice 租用了从 bottom 到 top(含 bottom 和 top 在内)的所有楼层。另给你一个整数数组 special ,其中 special[i] 表示 Alice 指定用于放松的特殊楼层。
返回不含特殊楼层的 最大 连续楼层数。
示例 1:
输入: bottom = 2, top = 9, special = [4,6]
输出: 3
解释: 下面列出的是不含特殊楼层的连续楼层范围:
- (2, 3) ,楼层数为 2 。
- (5, 5) ,楼层数为 1 。
- (7, 9) ,楼层数为 3 。
因此,返回最大连续楼层数 3 。
示例 2:
输入: bottom = 6, top = 8, special = [7,6,8]
输出: 0
解释: 每层楼都被规划为特殊楼层,所以返回 0 。
提示
1 <= special.length <= 1051 <= bottom <= special[i] <= top <= 109special中的所有值 互不相同
解法
class Solution {
/*
把bottom和top加入数组,
取每2个数字差的最大值。注意bottom、top需要包含这一边界条件
*/
public int maxConsecutive(int bottom, int top, int[] special) {
Arrays.sort(special);
List<Integer> list = Arrays.stream(special).boxed().collect(Collectors.toList());
list.add(0, bottom);
list.add(list.size(), top);
int res = 0;
// System.out.println(list);
for (int i = 0; i < list.size() - 1; i++) {
res = Math.max(res, list.get(i + 1) - list.get(i) - ((i + 1 == list.size() - 1 || i == 0) ? 0 : 1));
}
return res;
}
}
题目3
位运算的一个题: leetcode.cn/contest/wee…
题目4
6066. 统计区间中的整数数目
显示英文描述
- 通过的用户数489
- 尝试过的用户数1776
- 用户总通过次数614
- 用户总提交次数4520
- 题目难度Hard
给你区间的 空 集,请你设计并实现满足要求的数据结构:
- 新增: 添加一个区间到这个区间集合中。
- 统计: 计算出现在 至少一个 区间中的整数个数。
实现 CountIntervals 类:
CountIntervals()使用区间的空集初始化对象void add(int left, int right)添加区间[left, right]到区间集合之中。int count()返回出现在 至少一个 区间中的整数个数。
注意: 区间 [left, right] 表示满足 left <= x <= right 的所有整数 x 。
示例 1:
输入
["CountIntervals", "add", "add", "count", "add", "count"]
[[], [2, 3], [7, 10], [], [5, 8], []]
输出
[null, null, null, 6, null, 8]
解释
CountIntervals countIntervals = new CountIntervals(); // 用一个区间空集初始化对象
countIntervals.add(2, 3); // 将 [2, 3] 添加到区间集合中
countIntervals.add(7, 10); // 将 [7, 10] 添加到区间集合中
countIntervals.count(); // 返回 6
// 整数 2 和 3 出现在区间 [2, 3] 中
// 整数 7、8、9、10 出现在区间 [7, 10] 中
countIntervals.add(5, 8); // 将 [5, 8] 添加到区间集合中
countIntervals.count(); // 返回 8
// 整数 2 和 3 出现在区间 [2, 3] 中
// 整数 5 和 6 出现在区间 [5, 8] 中
// 整数 7 和 8 出现在区间 [5, 8] 和区间 [7, 10] 中
// 整数 9 和 10 出现在区间 [7, 10] 中
提示:
1 <= left <= right <= 109- 最多调用
add和count方法 总计105次 - 调用
count方法至少一次
解法
import java.util.*;
import java.util.stream.Collectors;
public class Problem6066 {
public static void main(String[] args) {
CountIntervals obj = new CountIntervals();
//[[], [2, 3], [7, 10], [], [5, 8], []]
obj.add(2, 3);
obj.add(7, 10);
obj.add(7, 7);
System.out.println(obj.count());
obj.add(5, 8);
System.out.println(obj.count());
}
/*
尝试1:超内存,不能new太大的空间 new boolean[1 * (int)Math.pow(10, 9)]
*/
static class CountIntervals1 {
private boolean[] arr = new boolean[1 * (int)Math.pow(10, 9)];
public CountIntervals1() {
}
public void add(int left, int right) {
for (int i = left; i <= right; i++) {
arr[i] = true;
}
}
public int count() {
int res = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i]) {
res++;
}
}
return res;
}
}
/*
尝试2:超内存。
遇到此case时候:
["CountIntervals","count","add","count"]
[[],[],[1,1000000000],[]]
set中就需要存1000000000个元素
*/
static class CountIntervals2 {
// private boolean[] arr = new boolean[1 * (int)Math.pow(10, 9)];
private Set<Integer> set = new HashSet<>();
public CountIntervals2() {
}
public void add(int left, int right) {
for (int i = left; i <= right; i++) {
set.add(i);
}
}
public int count() {
return set.size();
}
}
/*
通过部分用例,看题解说用线段树
我的解决思路是 区间合并,每次新插入的这个区间和已存在的进行判断合并,移除老区间,插入更长的新区间。
最后对每个区间长度求和
但部分用例过不了。。
*/
static class CountIntervals {
// private boolean[] arr = new boolean[1 * (int)Math.pow(10, 9)];
private List<Integer[]> list = new ArrayList<>();
public CountIntervals() {
}
// [[],[2,3],[7,10],[],[5,8],[]]
public void add(int left, int right) {
for (int i = 0; i < list.size(); i++) {
Integer[] itemArr = list.get(i);
if (!(left > itemArr[1] || right < itemArr[0])) {
left = Math.min(left, itemArr[0]);
right = Math.max(right, itemArr[1]);
// System.out.println(i);
list.remove(i);
i++;
}
}
list.add(new Integer[] {left, right});
}
public int count() {
int res = 0;
for (int i = 0; i < list.size(); i++) {
Integer[] itemArr = list.get(i);
res += (itemArr[1] - itemArr[0] + 1);
}
return res;
}
}
/**
* Your CountIntervals object will be instantiated and called as such:
* CountIntervals obj = new CountIntervals();
* obj.add(left,right);
* int param_2 = obj.count();
*/
}