[Leetcode Weekly Contest]319
链接:LeetCode
[Leetcode]2469. 温度转换
给你一个四舍五入到两位小数的非负浮点数 celsius 来表示温度,以 摄氏度(Celsius)为单位。
你需要将摄氏度转换为 开氏度(Kelvin)和 华氏度(Fahrenheit),并以数组 ans = [kelvin, fahrenheit] 的形式返回结果。
返回数组 ans 。与实际答案误差不超过 10-5 的会视为正确答案。
注意:
开氏度 = 摄氏度 + 273.15
华氏度 = 摄氏度 * 1.80 + 32.00
按题意模拟即可。
class Solution {
public double[] convertTemperature(double celsius) {
double[] res = new double[2];
res[0] = celsius + 273.15;
res[1] = celsius * 1.8 + 32;
return res;
}
}
[Leetcode]2470. 最小公倍数为 K 的子数组数目
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 nums 的 子数组 中满足 元素最小公倍数为 k 的子数组数目。
子数组 是数组中一个连续非空的元素序列。
数组的最小公倍数 是可被所有数组元素整除的最小正整数。
遍历即可,注意两数乘积=最大公约数*最小公倍数。
class Solution {
public int subarrayLCM(int[] nums, int k) {
int n = nums.length;
int res = 0;
for(int i=0;i<n;++i) {
int p = nums[i];
for(int j=i;j<n;++j) {
int g = gcd(p, nums[j]);
p = p * nums[j] / g;
if(p == k) res ++;
if(p > k) break;
}
}
return res;
}
public int gcd(int p, int q) {
return q == 0 ? p : gcd(q, p%q);
}
}
[Leetcode]2471. 逐层排序二叉树所需的最少操作数目
给你一个 值互不相同 的二叉树的根节点 root 。
在一步操作中,你可以选择 同一层 上任意两个节点,交换这两个节点的值。
返回每一层按 严格递增顺序 排序所需的最少操作数目。
节点的 层数 是该节点和根节点之间的路径的边数。
本题可以分解下面两个小问题:
- 为层序遍历提取出每层所含的节点值
- 对每层节点计算得到完全递增结果的需要的最小交换次数
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int minimumOperations(TreeNode root) {
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int res = 0;
while(queue.size()!=0) {
int size = queue.size();
int[] nums = new int[size];
for(int i=0;i<size;++i) {
var node = queue.poll();
nums[i] = node.val;
if(node.left!=null) {
queue.offer(node.left);
}
if (node.right!=null) {
queue.offer(node.right);
}
}
res += getMinimumOperations(nums);
}
return res;
}
public int getMinimumOperations(int[] nums) {
int res = 0, n = nums.length;
if(n == 0) return res;
int[] sortedNums = Arrays.copyOf(nums, n);
Arrays.sort(nums);
HashMap<Integer, Integer> hash = new HashMap<>();
for(int i=0;i<n;++i) hash.put(nums[i], i);
for(int i=0;i<n;++i) {
if(nums[i] != sortedNums[i]) {
var index = hash.get(sortedNums[i]);
hash.put(nums[index], i);
hash.put(nums[i], index);
swap(nums, i, index);
res ++;
}
}
return res;
}
public void swap(int[] nums, int i, int j) {
nums[i] ^= nums[j];
nums[j] ^= nums[i];
nums[i] ^= nums[j];
}
}
[Leetcode]2472. 不重叠回文子字符串的最大数目
给你一个字符串 s 和一个 正 整数 k 。
从字符串 s 中选出一组满足下述条件且 不重叠 的子字符串:
- 每个子字符串的长度 至少 为 k 。
- 每个子字符串是一个 回文串 。
返回最优方案中能选择的子字符串的 最大 数目。
子字符串 是字符串中一个连续的字符序列。
求出每个子串是不是回文子串。记 \(g(l,r)\) 表示第 l 到 r 个字符构成的子串是不是回文子串。
之后维护 f(i) 表示长度为 的前缀中能选出多少个长度大等于 k 且不重叠的子串,转移方程为
上面的转移表示不选择以第 i 个字符为结尾的子串;下面的转移表示选择以第(j+1) 个字符为开始,第i个字符为结束的回文子串。
初值 \(f(0)=0\),答案就是 \(f(n)\),复杂度 \(\mathcal{O}(n^2)\)。
class Solution {
public int maxPalindromes(String s, int k) {
int n = s.length();
if(k==1) return n;
int[] dp = new int[n+1];
for(int i=0;i<n;++i) {
dp[i+1] = dp[i];
for(int j=i-k+1;j>=0;--j) {
if(isPalindrome(s.substring(j,i+1))) {
dp[i+1] = Math.max(dp[i+1], dp[j] + 1);
break;
}
}
}
return dp[n];
}
public boolean isPalindrome(String s) {
int i = 0, j = s.length()-1;
while(i < j) {
if(s.charAt(i) != s.charAt(j)) return false;
i++;
j--;
}
return true;
}
}
参考:LeetCode