2020年8月1日 最小区间 smallestRange
class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
}
}
解题思路:
首先我们理解题意,要我们求什么?
题目中给出了对于最小区间一词中“最小”的概念的定义。
b-a<d-c那么 区间[a,b]小于[d,c],也就是数组[1,3]小于数组[1,4],这里的小是指能够表示的范围更小
b-a==d-c时 a<c ,之句话是指对于[1,3]和[4,6]他们表示的范围是一样大,但是[1,3]中包含的最小值更小,所以定义[1,3]更小
解决方案:
滑动窗口
我们构建一种对象,里面包含三个值,蓝色的表示在链表中的值,绿色表示的是第几个链表,黄色表示的是在链表中的第几个。(蓝色的值可以不要,绿色和黄色的值已经能找出该值了)
比如上图,解释一下上图的含义。
红色标记的是链表中的当前在我们处理链表中的节点,我们的链表长度和链表的个数一样是k
并且我们的链表也是有排序的,是一个升序的链表。
我们先用所有链表的第一个节点来初始化我们的链表并且排序。
先计算当前的最小区间,最小值1,最大值2,得到区间[1,2]
然后我们取出链表中第一个节点(最小的),找到他所在的链表,将节点右移一位。
得到新的节点,并且在我们的链表中排序。
得到区间[1,2]
此时最小的变为第1个链表的第1个节点,我们将其后移,得到新的区间[2,3]
我们循环至最小的那个节点所在链表的尾部,也就是我们取出最小值后,该节点在他的链表中无法右移了,那么这个区间只会变大不会变小了,我们就可以不用计算了。
代码实现。
class myNode{
int val;
int id;
int index;
myNode(int val,int id,int index){
this.val=val;
this.id=id;
this.index=index;
}
}
public int[] smallestRange(List<List<Integer>> nums) {
int len=nums.size();
//初始化滑动窗口,工具链表
LinkedList<myNode> myNodes=new LinkedList<>();
//第一个节点手动加入
myNode node=new myNode(nums.get(0).get(0),0 ,0 );
myNodes.add(node);
//遍历所有链表的第一个节点,加入链表并且排序
for (int i=1;i<len;i++){
//获取在链表中的值
int val=nums.get(i).get(0);
for (int j=0;j<myNodes.size()