一、leetcode题目
1.多余的边
题目描述
树可以看成是一个连通且 无环 的 无向 图。
给定往一棵 n
个节点 (节点值 1~n
) 的树中添加一条边后的图。添加的边的两个顶点包含在 1
到 n
中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n
的二维数组 edges
,edges[i] = [ai, bi]
表示图中在 ai
和 bi
之间存在一条边。
请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n
个节点的树。如果有多个答案,则返回数组 edges
中最后出现的边。
2.测试用例
输入:
[[1,2],[1,3],[2,3]]
输出:
解释:
[2,3]
提示
- n == edges.length
- 3 <= n <= 1000
- edges[i].length == 2
- 1 <= ai < bi <= edges.length
- ai != bi
- edges 中无重复元素
- 给定的图是连通的
3.思路
数组中存储的是无向图的连接边,直接遍历建图,在构建某一条边的时候,如果建立这条边,使我们构建的图形成了构成了环,那就找到了我们需要删除的边。算法可以选择并查集。
4.算法实现
class Solution {
public int[] findRedundantConnection(int[][] edges) {
int[] parent = new int[edges.length+1];
for(int i = 0; i < parent.length; i++){
parent[i] = i;
}
for(int[] edge : edges){
if(find(parent, edge[0]) == find(parent, edge[1])) return edge;
union(parent, edge[0], edge[1]);
}
return new int[2];
}
// 并查集中的合并操作
private void union(int[] parent, int a, int b){
parent[find(parent, a)] = find(parent, parent[b]);
}
// 并查集中的查找操作
private int find(int[] parent, int x){
if(parent[x] != x) parent[x] = find(parent, parent[x]);
return parent[x];
}
}
二、蓝桥题目
1.MAX最差值
题目描述
给定一个长度为 NN 的数组 aa 和一个常数 kk,数组的值分别为
a
1
,
a
2
,
.
.
.
,
a
N
a_1,a_2,...,a_N
a1,a2,...,aN.
定义 F ( i ) F(i) F(i) 表示区间 [ m a x ( 1 , i − k ) , i ] [max(1,i - k),i] [max(1,i−k),i] 的最小值,G(i)G(i) 表示区间 [ m a x ( 1 , i − k ) , i ] [max(1,i - k),i] [max(1,i−k),i] 的最大值。
请你求出
G
(
i
)
−
F
(
i
)
G(i) - F(i)
G(i)−F(i) 的最大值。
输入描述
输入第 11 行包含两个正整数 N,kN,k。
第 2 2 2 行包含 N N N 个非负整数 a 1 , a 2 , . . . , a N a_1,a_2,...,a_N a1,a2,...,aN,表示数组 a a a 元素的值。
1 ≤ N , k ≤ 1 0 6 1 ≤ N , k ≤ 1 0 6 1\leq N,k \leq 10^61≤N,k≤10^6 1≤N,k≤1061≤N,k≤106
输出描述
输出共 1 1 1 行,包含一个整数,表示答案。
2.测试用例
输入:
6 3
4 6 5 2 3 1
输出:
4
3.思路
建立两个双向队列,一个队列顶部维护最大值(类似于单调栈),一个队列顶部维护最小值,测试用例中没有说清楚,数组中的数字是否有重复值。不过应该是有重复值,测试用例过的不多。
4.算法实现
import java.util.Scanner;
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n = scan.nextInt(), k = scan.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = scan.nextInt();
}
LinkedList<Integer> queue1 = new LinkedList<>();
LinkedList<Integer> queue2 = new LinkedList<>();
for(int i = 0 ; i < k; i++){
while(!queue1.isEmpty() && queue1.peekLast() < arr[i]) queue1.removeLast();
while(!queue2.isEmpty() && queue2.peekLast() > arr[i]) queue2.removeLast();
queue1.addLast(arr[i]);
queue2.addLast(arr[i]);
}
int max = queue1.peekFirst() - queue2.peekFirst();
for(int i = k; i < n; i++){
while(!queue1.isEmpty() && queue1.peekLast() < arr[i]) queue1.removeLast();
while(!queue2.isEmpty() && queue2.peekLast() > arr[i]) queue2.removeLast();
queue1.addLast(arr[i]);
queue2.addLast(arr[i]);
if(!queue1.isEmpty() && queue1.peekFirst() == arr[i-k]) queue1.removeFirst();
if(!queue2.isEmpty() && queue2.peekFirst() == arr[i-k]) queue1.removeFirst();
max = Math.max(max, queue1.peekFirst() - queue2.peekFirst());
}
System.out.println(max);
scan.close();
}
}