[Leetcode Weekly Contest]259
链接:LeetCode
[Leetcode]2011. 执行操作后的变量值
存在一种仅支持 4 种操作和 1 个变量 X 的编程语言:
++X 和 X++ 使变量 X 的值 加 1
--X 和 X-- 使变量 X 的值 减 1
最初,X 的值是 0
给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有操作后, X 的 最终值 。
遍历即可。
class Solution {
public int finalValueAfterOperations(String[] operations) {
int res = 0;
for(var operation:operations) {
if(operation.contains("--")){
res --;
}
else {
res ++;
}
}
return res;
}
}
[Leetcode]2012. 数组美丽值求和
给你一个下标从 0 开始的整数数组 nums 。对于每个下标 i(1 <= i <= nums.length - 2),nums[i] 的 美丽值 等于:
- 2,对于所有 0 <= j < i 且 i < k <= nums.length - 1 ,满足 nums[j] < nums[i] < nums[k]
- 1,如果满足 nums[i - 1] < nums[i] < nums[i + 1] ,且不满足前面的条件
- 0,如果上述条件全部不满足
返回符合 1 <= i <= nums.length - 2 的所有 nums[i] 的 美丽值的总和 。
根据题意,依次判断条件即可。难点在于判断美丽值是否为2的条件,即需要判断中间的数满足大于左边所有数,并且小于右边所有数。也就是,中间的数需要大于左边最大的数,小于右边最小的数。我们可以先遍历两遍数值,得出每个索引位置左边最大数和右边最小数,最后判断即可。
class Solution {
public int sumOfBeauties(int[] nums) {
int n = nums.length;
int[] leftMax = new int[n];
int [] rightMin = new int[n];
leftMax[0] = -1;
rightMin[n-1] = Integer.MAX_VALUE;
for(int i=1;i<n;++i){
leftMax[i] = Math.max(leftMax[i-1],nums[i-1]);
}
for(int i=n-2;i>=0;--i) {
rightMin[i] = Math.min(rightMin[i+1],nums[i+1]);
}
int res = 0;
for(int i=1;i<n-1;++i) {
if(nums[i] > leftMax[i] && nums[i] < rightMin[i]) {
res += 2;
}
else if(nums[i] > nums[i-1] && nums[i] < nums[i+1]) {
res += 1;
}
}
return res;
}
}
[Leetcode]2013. 检测正方形
给你一个在 X-Y 平面上的点构成的数据流。设计一个满足下述要求的算法:
添加 一个在数据流中的新点到某个数据结构中。可以添加 重复 的点,并会视作不同的点进行处理。
给你一个查询点,请你从数据结构中选出三个点,使这三个点和查询点一同构成一个 面积为正 的 轴对齐正方形 ,统计 满足该要求的方案数目。
轴对齐正方形 是一个正方形,除四条边长度相同外,还满足每条边都与 x-轴 或 y-轴 平行或垂直。
实现 DetectSquares 类:
DetectSquares() 使用空数据结构初始化对象
void add(int[] point) 向数据结构添加一个新的点 point = [x, y]
int count(int[] point) 统计按上述方式与点 point = [x, y] 共同构造 轴对齐正方形 的方案数。
枚举所有对角线的点判断是否构成正方形即可。
class DetectSquares {
Map<String, Integer> map;
public DetectSquares() {
map = new HashMap<>();
}
public void add(int[] point) {
String key = point[0] + "," + point[1];
map.put(key, map.getOrDefault(key, 0) + 1);
}
public int count(int[] point) {
int res = 0;
int x = point[0];
int y = point[1];
for (String key : map.keySet()) {
int delX = Integer.parseInt(key.split(",")[0]);
int delY = Integer.parseInt(key.split(",")[1]);
int delCnt = map.get(key);
if (delX != x && delY != y && Math.abs(delX - x) == Math.abs(delY - y) && delCnt > 0) {
int xParCnt = map.getOrDefault(delX + "," + y, 0);
int yParCnt = map.getOrDefault(x + "," + delY, 0);
res += delCnt * xParCnt * yParCnt;
}
}
return res;
}
}
[Leetcode]2014. 重复 K 次的最长子序列
给你一个长度为 n 的字符串 s ,和一个整数 k 。请你找出字符串 s 中 重复 k 次的 最长子序列 。
子序列 是由其他字符串删除某些(或不删除)字符派生而来的一个字符串。
如果 seq * k 是 s 的一个子序列,其中 seq * k 表示一个由 seq 串联 k 次构造的字符串,那么就称 seq 是字符串 s 中一个 重复 k 次 的子序列。
举个例子,"bba" 是字符串 "bababcba" 中的一个重复 2 次的子序列,因为字符串 "bbabba" 是由 "bba" 串联 2 次构造的,而 "bbabba" 是字符串 "bababcba" 的一个子序列。
返回字符串 s 中 重复 k 次的最长子序列 。如果存在多个满足的子序列,则返回 字典序最大 的那个。如果不存在这样的子序列,返回一个 空 字符串。
BFS。由于一共就26个字母,遍历字母组合即可。
class Solution {
public String longestSubsequenceRepeatedK(String s, int k) {
String res = "";
// q保存只放可行子串
Queue<String> q = new LinkedList<>();
q.add("");
while (!q.isEmpty()) {
int size = q.size();
// 按层BFS,同层长度相同
while (size-- > 0) {
String cur = q.poll();
for (int i = 0; i < 26; i++) {
String next = cur + (char) ('a' + i);
if (isSub(s, next, k)) {
// 找最大的,所以要更新
res = next;
q.add(next);
}
}
}
}
return res;
}
// sub * k 是否 s的子串.
private boolean isSub(String s, String sub, int k) {
int j = 0;
int repeat = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == sub.charAt(j)) {
j++;
if (j == sub.length()) {
repeat++;
if (repeat == k) {
return true;
}
j = 0;
}
}
}
return false;
}
}