Per questa domanda è possibile utilizzare segment tree. This è uno dei migliori tutorial sull'intervallo di segmenti e nell'intervallo minimo di query.
Fornisco l'implementazione JAVA e il codice è autoesplicativo, per favore fatemi sapere se avete dei dubbi.
public class SegmentTree {
private int[] array;
private int length;
public static SegmentTree initialize(int[] a) {
return new SegmentTree(a);
}
private SegmentTree(int[] a) {
length = a.length - 1;
int l = (int) (Math.log(a.length)/Math.log(2));
l = (int) (Math.pow(2, l + 1) * 2 - 1);
array = new int[l];
initialize(a, 0, a.length - 1, 0);
}
private int initialize(int[] a, int p, int r, int index) {
if (p == r) {
array[index] = a[p];
return a[p];
}
int q = p + (r - p)/2;
array[index] = Math.min(initialize(a, p, q, 2 * index + 1), initialize(a, q + 1, r, 2 * index + 2));
return array[index];
}
public int findMin(int p, int r) {
return _findMin(p, r, 0, length, 0);
}
private int _findMin(int qs, int qe, int ss, int se, int i) {
if (qs <= ss && se <= qe) {
return array[i];
}
if (qs > se || qe < ss) {
return Integer.MAX_VALUE;
}
int q = ss + (se - ss)/2;
return Math.min(_findMin(qs, qe, ss, q, 2 * i + 1), _findMin(qs, qe, q + 1, se, 2 * i + 2));
}
private void print() {
int index = 0;
for (int k : array) {
System.out.println(index + ":" + k);
index++;
}
}
public static void main(String[] args) {
int[] a = {1, 34, 5, 6, 78, 5, 67, 89};
SegmentTree s = initialize(a);
System.out.println(s.findMin(2, 4));
}
}
Sembra che sia necessario solo per il ciclo – LeeNeverGup
E questo è lineare ... Non è possibile andare più veloce? –
È possibile precomputare il risultato una volta per ogni intervallo possibile nel tempo 'O (N^2)'. Dopo di ciò, la ricerca sarà costante. A seconda della frequenza con cui devi cercare gli stessi dati, potresti essere in grado di ammortizzare il costo iniziale. –