Bạn có thể sử dụng segment tree cho câu hỏi này. This là một trong những hướng dẫn tốt nhất về phân đoạn truy vấn tối thiểu cây và phạm vi.
Tôi đang thực hiện JAVA và mã tự giải thích, vui lòng cho tôi biết nếu bạn có bất kỳ nghi ngờ nào.
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));
}
}
Dường như bạn chỉ cần cho vòng lặp – LeeNeverGup
Và đó là tuyến tính ... Không phải là nó có thể đi nhanh hơn? –
Bạn có thể tính trước kết quả một lần cho mọi phạm vi có thể trong thời gian 'O (N^2)'. Sau đó, tra cứu sẽ là thời gian không đổi. Tùy thuộc vào mức độ thường xuyên bạn cần tìm kiếm trên cùng một dữ liệu, bạn có thể phân bổ chi phí ban đầu. –