虚拟机网络连接
首先找到主机的网络连接: 首先我的情况是需要将虚拟机的网络与主机的wifi相连接,也就是主机上的WLAN网。
第一步就是在网络连接中先把WLAN的连接共享打开。
第二步,直接打开虚拟机的虚拟网络编辑器
第三步,加一个Vment0,为桥接模式,然后下方的连接到改成WLAN中的名称。
最后一步,把网络适配器改成自定义Vment0
重启虚拟机即可连上网络
包含每个查询的最小区间(困难)
题目描述
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示第 i个区间开始于 lefti 、结束于 righti(包含两侧取值,闭区间)。区间的 长度 定义为区间中包含的整数数目,更正式地表达是 righti - lefti + 1 。
再给你一个整数数组 queries 。第 j 个查询的答案是满足 lefti <= queries[j] <= righti 的 长度最小区间 i 的长度 。如果不存在这样的区间,那么答案是 -1 。
以数组形式返回对应查询的所有答案。
示例 1:
输入:intervals = [[1,4],[2,4],[3,6],[4,4]], queries = [2,3,4,5] 输出:[3,3,1,4] 解释:查询处理如下:
- Query = 2 :区间 [2,4] 是包含 2 的最小区间,答案为 4 - 2 + 1 = 3 。
- Query = 3 :区间 [2,4] 是包含 3 的最小区间,答案为 4 - 2 + 1 = 3 。
- Query = 4 :区间 [4,4] 是包含 4 的最小区间,答案为 4 - 4 + 1 = 1 。
- Query = 5 :区间 [3,6] 是包含 5 的最小区间,答案为 6 - 3 + 1 = 4 。 示例 2:
输入:intervals = [[2,3],[2,5],[1,8],[20,25]], queries = [2,19,5,22] 输出:[2,-1,4,6] 解释:查询处理如下:
- Query = 2 :区间 [2,3] 是包含 2 的最小区间,答案为 3 - 2 + 1 = 2 。
- Query = 19:不存在包含 19 的区间,答案为 -1 。
- Query = 5 :区间 [2,5] 是包含 5 的最小区间,答案为 5 - 2 + 1 = 4 。
- Query = 22:区间 [20,25] 是包含 22 的最小区间,答案为 25 - 20 + 1 = 6 。
解题思路:
首先将二维数组拆分为一位数组,然后可以计算出同一行俩个数之间的差值。依次比较queries数组中的数是否满足条件。同时先取一个大值num=1e7 。 如果该行满足条件,将num改为此行的right-left+1.然后遍历整个二维数组的所有行,得到最小的num值。
代码如下:
func minInterval(intervals [][]int, queries []int) []int {
leng := len(intervals) //行长度
leng2 := len(queries) //需检查长度
numbers := make([]int, leng2)
for j := 0; j < leng2; j++ {
num := 10000000
for i := 0; i < leng; i++ {
add := intervals[i]
if queries[j] >= add[0] && queries[j] < add[1]+1 {
if num > add[1]-add[0]+1 { // Fix the comparison condition
num = add[1] - add[0] + 1
}
}
}
if num == 10000000 {
num = -1
}
numbers[j] = num
}
return numbers
}
但是很可惜,,,超时了(果然不出所料呢),嵌套循环果然容易遭。
官方解答
方法:排序 + 离线查询 + 并查集
我们注意到,题目中查询的顺序并不会影响答案,并且涉及到的区间也不会发生变化,因此,我们考虑将所有的查询按照从小到大的顺序进行排序,同时将所有的区间按照左端点从小到大的顺序进行排序。(这一块没想到,可以节省时间的)
换个角度,对每个区间,去回答包含这个区间的询问。
按照区间长度从小到大排序,遍历每个区间,我们可以直接回答在该区间内的尚未被回答的询问,这是因为区间是按长度从小到大排序的,这些未被回答的询问所需要找的最小区间就是当前区间。
由于一个区间内可能存在已经被回答过的询问,所以我们需要跳过这些询问,这可以用并查集来维护,当我们回答一个区间时,将区间所有元素指向其下一个元素,这样当我们用并查集查询到一个回答完毕的区间的左端点时,自然就跳到了区间的右端点的右侧。
并查集理解:
并查集的 fa 数组,索引对应查询的索引,保存的值是 下一个(更大的/更靠右的)未回答的查询的位置
二分查找找到的查询保证 满足目前区间的左边界,下一步是从找到的查询开始,找到满足区间右边界,且没有被回答过的查询 通过并查集数组,就可以找到下一个未回答的查询 假设查询为 q = [2, 3, 4, 5],fa = [0, 1, 2, 3, 4 ]
当前区间为 [4, 4],
- 二分查到 位置是 2,左边界满足了;
- 查询 fa[2] = 2, q[2] = 4 <= 4,满足右边界,记录结果,同时把 fa[2] 指向 2+1,下一个位置。翻译过来就是,已经找过我了,以后再找我的话,去找下一位。fa = [0, 1, 3, 3, 4],下一位 fa[3] = 3,但是 q[3] = 5 > 4不满足右边界,停止
下一区间为[3, 5],
- 二分查找 位置是 1,满足了左边界;
- 查询fa[1] = 1 (还没有找过 1),q[1] = 3 < 5,满足右边界,记录结果,同时把 fa[1] 指向 1 + 1 = 2, fa = [0. 2, 3, 3, 4],下一位是 fa[2] = 3,q[3] <= 5,满足右边界,记录结果,fa[3] = 4,fa = [0. 2, 3, 4, 4],超过数组边界,停止。现在可以看到,再去找 1, 2, 或者 3的时候,已经找不到了,因为 fa[1], fa[2], fa[3] 指向的都不是它们自己的索引了。
代码如下
func minInterval(intervals [][]int, queries []int) []int {
// 按照区间长度由小到大排序,这样每次回答的时候用的就是长度最小的区间
sort.Slice(intervals, func(i, j int) bool {
a, b := intervals[i], intervals[j]; return a[1]-a[0] < b[1]-b[0] })
m := len(queries)
type pair struct{ pos, i int }
qs := make([]pair, m)
for i, q := range queries {
qs[i] = pair{q, i}
}//这是类似弄了一个Index出来,很有用感觉
// 离线:按查询位置排序
sort.Slice(qs, func(i, j int) bool { return qs[i].pos < qs[j].pos })
// 初始化并查集
fa := make([]int, m+1)
for i := range fa {
fa[i] = i
}
var find func(int) int
find = func(x int) int {
if fa[x] != x {
fa[x] = find(fa[x])
}
return fa[x]
}
ans := make([]int, m)
for i := range ans {
ans[i] = -1
}
// 对每个区间,回答所有在 [l,r] 范围内的询问
// 由于每次回答询问之后,都将其指向了下一个询问
// 所以若 i = find(i) 符合 i < m && qs[i].pos <= r 的条件,则必然是一个在 [l,r] 范围内的还没有回答过的询问
for _, p := range intervals {
l, r := p[0], p[1]
length := r - l + 1
// 二分找大于等于区间左端点的最小询问
i := sort.Search(m, func(i int) bool { return qs[i].pos >= l })
// 回答所有询问位置在 [l,r] 范围内的还没有被回答过的询问
for i = find(i); i < m && qs[i].pos <= r; i = find(i + 1) {
ans[qs[i].i] = length
fa[i] = i + 1
}
}
return ans
}
作者:endlesscheng
链接:https://leetcode.cn/problems/minimum-interval-to-include-each-query/solution/an-qu-jian-chang-du-pai-xu-chi-xian-bing-6jzs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解释一下代码:
// 按照区间长度由小到大排序,这样每次回答的时候用的就是长度最小的区间
sort.Slice(intervals, func(i, j int) bool {
a, b := intervals[i], intervals[j]; return a[1]-a[0] < b[1]-b[0] })
这一点点好像就是我开始所写的内容,即比较俩行之间的差值大小,返回小的。这就是大佬的代码吗Orz。
sort.Slice:这是 Go 中 sort 包中的函数。它允许您使用自定义比较函数对切片进行排序。
intervals:这是您要排序的二维数组。它包含一个间隔列表,其中每个间隔表示为两个整数 [start, end] 的切片。
func(i, j int) bool { ... }:这是一个匿名(未命名)函数,也称为函数文字或 lambda 函数。它定义了用于对间隔进行排序的自定义比较函数。
a, b :=Intervals[i],Intervals[j]:这一行从切片中提取两个区间Intervals[i]和Intervals[j]来比较它们。
return a[1]-a[0] < b[1]-b[0]:这是比较逻辑。它计算每个间隔的大小(结束 - 开始),然后比较它们。如果区间 a 的大小小于区间 b 的大小,则该函数返回 true,这意味着按排序顺序 a 应位于 b 之前。否则,它返回 false,这意味着 b 应该出现在 a 之前。
type pair struct{ pos, i int }
qs := make([]pair, m)
for i, q := range queries {
qs[i] = pair{q, i}
}
此循环使用 range 关键字迭代查询切片中的每个元素。对于每个查询 q 及其索引 i,它创建一个新的pair结构并将其分配给 qs 切片中相应的索引 i。 pair 结构体的 pos 字段设置为查询 q 的值,i 字段设置为查询 i 的原始索引
本质上,执行此代码后,qs 切片将包含查询切片中每个元素的{query_value,original_index} 形式的对。当您想要跟踪查询的原始索引同时以不同的顺序处理它们时,此转换非常有用。