第二次-320场周赛

第一题:数组中不等三元组的数目

给你一个下标从 0 开始的正整数数组 nums 。请你找出并统计满足下述条件的三元组 (i, j, k) 的数目:

  • 0 <= i < j < k < nums.length
  • nums[i]nums[j]nums[k] 两两不同 。
    • 换句话说:nums[i] != nums[j]nums[i] != nums[k]nums[j] != nums[k]

返回满足上述条件三元组的数目

示例 1:

1
2
3
4
5
6
7
8
9
输入:nums = [4,4,2,4,3]
输出:3
解释:下面列出的三元组均满足题目条件:

- (0, 2, 4) 因为 4 != 2 != 3
- (1, 2, 4) 因为 4 != 2 != 3
- (2, 3, 4) 因为 2 != 4 != 3
共计 3 个三元组,返回 3 。
注意 (2, 0, 4) 不是有效的三元组,因为 2 > 0

示例 2:

1
2
3
输入:nums = [1,1,1,1,1]
输出:0
解释:不存在满足条件的三元组,所以返回 0 。

+++++++++++++++

简单题

思路:自己用暴力做的

代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public static int unequalTriplets(int[] nums) {
int len = nums.length;
int res = 0;
for (int i = 0;i<len;i++){
for (int l = i+1;l<len-1;l++){
int r = l + 1;
while (r<len) {
if (nums[i] == nums[l] || nums[i] == nums[r] || nums[l] == nums[r]) {
r++;
} else {
r++;
res++;
}
}
}
}
return res;
}
}

很妙的思路:https://leetcode.cn/problems/number-of-unequal-triplets-in-array/solution/fei-bao-li-zuo-fa-by-endlesscheng-9ekp/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public static int unequalTriplets(int[] nums) {
Arrays.sort(nums);
int res = 0;
for (int i = 0,r = 1;r<nums.length;){
if (nums[i]!=nums[r]){
res+=i*(r-i)*(nums.length-r);
i = r;
}else {
r++;
}
}
return res;
}
}

第二题:二叉搜索树最近节点查询

给你一个 二叉搜索树 的根节点 root ,和一个由正整数组成、长度为 n 的数组 queries

请你找出一个长度为 n 的 二维 答案数组 answer ,其中 answer[i] = [mini, maxi]

  • mini 是树中小于等于 queries[i] 的 最大值 。如果不存在这样的值,则使用 -1 代替。
  • maxi 是树中大于等于 queries[i] 的 最小值 。如果不存在这样的值,则使用 -1 代替。

返回数组 answer

示例 1 :

img

1
2
3
4
5
6
输入:root = [6,2,13,1,4,9,15,null,null,null,null,null,null,14], queries = [2,5,16]
输出:[[2,2],[4,6],[15,-1]]
解释:按下面的描述找出并返回查询的答案:
- 树中小于等于 2 的最大值是 2 ,且大于等于 2 的最小值也是 2 。所以第一个查询的答案是 [2,2] 。
- 树中小于等于 5 的最大值是 4 ,且大于等于 5 的最小值是 6 。所以第二个查询的答案是 [4,6] 。
- 树中小于等于 16 的最大值是 15 ,且大于等于 16 的最小值不存在。所以第三个查询的答案是 [15,-1] 。

示例 2 :

img

1
2
3
输入:root = [4,null,9], queries = [3]
输出:[[-1,4]]
解释:树中不存在小于等于 3 的最大值,且大于等于 3 的最小值是 4 。所以查询的答案是 [-1,4] 。

++++++++++++

中等题

思路首先对树进行遍历,存储到TreeSet中,因为TreeSet中有两个内置方法可以直接获取本题答案。

开始的时候用了二分查找,没有做出来,但感觉应该可以,也许是哪种情况没有考虑对把。我再去试试~~成功了!成功了!

TreeSet中的内置函数floorceiling,没有做出来,情况太多,内置函数真的太重要了!!

floor:方法返回在这个集合中小于或者等于给定元素的最大元素,如果不存在这样的元素,返回null.

ceiling:方法返回在这个集合中大于或者等于给定元素的最小元素,如果不存在这样的元素,返回null.

知道这两个方法这题瞬间就变为简单题,hhhh~

代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* 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 List<List<Integer>> closestNodes(TreeNode root, List<Integer> queries) {
TreeSet<Integer> set = new TreeSet<>();
inSearch(root,set);
List<List<Integer>> ans = new ArrayList<>();
for (int q : queries) {
Integer min = set.floor(q);
if (min == null) {
min = -1;
}
Integer max = set.ceiling(q);
if (max == null) {
max = -1;
}
List<Integer> list = new ArrayList<>();
list.add(min);
list.add(max);
ans.add(list);
}
return ans;
}
//树的遍历
public static void inSearch(TreeNode root,TreeSet<Integer> set){
if(root!=null){
inSearch(root.left,set);
set.add(root.val);
inSearch(root.right,set);
}
}
}

看吧!!!!哈哈哈 我就说可以嘛~

代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    /**
* 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 {
List<Integer> list = new ArrayList<>();
public List<List<Integer>> closestNodes(TreeNode root, List<Integer> queries) {
List<List<Integer>> res = new ArrayList<>();
inSearch(root);
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
for (int i = 0;i<queries.size();i++){
List<Integer> list2 = new ArrayList<>();
int a = queries.get(i);
list2.add(search1(arr,a));
list2.add(search2(arr,a));
res.add(list2);
}
return res;
}
public int search1(int arr[],int a){
int l = 0;
int r = arr.length-1;
while (l<r){
int mid = (l+r+1)/2;
if (arr[mid]<=a){
l = mid;
}else r = mid - 1;
}
return arr[l]<=a?arr[l]:-1;
}
public int search2(int arr[],int a){
int l = 0;
int r = arr.length-1;
while (l<r){
int mid = (l+r)/2;
if (arr[mid]>=a){
r = mid;
}else l = mid+1;
}
return arr[l]>=a?arr[l]:-1;
}
//树的遍历
public void inSearch(TreeNode root){
if(root!=null){
if (root.left!=null) inSearch(root.left);
list.add(root.val);
if (root.right!=null) inSearch(root.right);
}
}
}

第三题:到达首都的最少油耗

https://leetcode.cn/problems/minimum-fuel-cost-to-report-to-the-capital/

难呀难~~没怎么看懂。

简单写一下把。

给你一棵 n 个节点的树(一个无向、连通、无环图),每个节点表示一个城市,编号从 0n - 1 ,且恰好有 n - 1 条路。0 是首都。给你一个二维整数数组 roads ,其中 roads[i] = [ai, bi] ,表示城市 aibi 之间有一条 双向路 。

每个城市里有一个代表,他们都要去首都参加一个会议。

每座城市里有一辆车。给你一个整数 seats 表示每辆车里面座位的数目。

城市里的代表可以选择乘坐所在城市的车,或者乘坐其他城市的车。相邻城市之间一辆车的油耗是一升汽油。

请你返回到达首都最少需要多少升汽油。

示例 1:

img

1
2
3
4
5
6
7
输入:roads = [[0,1],[0,2],[0,3]], seats = 5
输出:3
解释:
- 代表 1 直接到达首都,消耗 1 升汽油。
- 代表 2 直接到达首都,消耗 1 升汽油。
- 代表 3 直接到达首都,消耗 1 升汽油。
最少消耗 3 升汽油。

示例 2:

img

1
2
3
4
5
6
7
8
9
10
11
输入:roads = [[3,1],[3,2],[1,0],[0,4],[0,5],[4,6]], seats = 2
输出:7
解释:
- 代表 2 到达城市 3 ,消耗 1 升汽油。
- 代表 2 和代表 3 一起到达城市 1 ,消耗 1 升汽油。
- 代表 2 和代表 3 一起到达首都,消耗 1 升汽油。
- 代表 1 直接到达首都,消耗 1 升汽油。
- 代表 5 直接到达首都,消耗 1 升汽油。
- 代表 6 到达城市 4 ,消耗 1 升汽油。
- 代表 4 和代表 6 一起到达首都,消耗 1 升汽油。
最少消耗 7 升汽油。

++++++++++

中等题

思路:将消耗的汽油转化消耗多少辆车,为以0为根节点,分别计算每个子树(每个子树也用同样的方式计算它们的子树–递归操作)所要消耗的车,最后结果相加。

消耗车的数量:每个连边所要经过的人/车的座位数=车的数量,将每个连边加在一起就是总共所需要的数量

代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
long res;
List<List<Integer>> list = new ArrayList<>();
public long minimumFuelCost(int[][] roads, int seats) {
int len = roads.length+1;
for (int i = 0;i<len;i++){
list.add(new ArrayList<>());
}
//建立图,双向边
for (int i = 0;i<roads.length;i++){
list.get(roads[i][0]).add(roads[i][1]);
list.get(roads[i][1]).add(roads[i][0]);
}
//以0为根节点,遍历子树
dfs(0,-1,seats);
return res;
}
public int dfs(int cur,int father,int seats){
int size = 1;
for (int i:list.get(cur)){
//因为是从根节点计算的,所以该节点与根节点连接的那条边就不用计算,因为在计算根节点的时候已经计算过了
if (i!=father){
size += dfs(i,cur,seats);
}
}
if (cur!=0) res+=(int)Math.ceil((double) size/seats); //每个子树需要车子的数量
return size;
}
}

第四题:完美分割的方案数

https://leetcode.cn/problems/number-of-beautiful-partitions/


第二次-320场周赛
http://example.com/2022/11/20/第二次-320场周赛/
作者
zlw
发布于
2022年11月20日
许可协议