Tạo một mảng smaller
và greater
, tương tự như những gì đã được thực hiện cho một dãy kích thước 3. Thêm vào đó, cũng có betweenSmallerAndCurrent
mảng lưu trữ chỉ mục của một giá trị nằm giữa phần tử nhỏ nhất và phần tử hiện tại - cả về giá trị và chỉ mục. Rõ ràng hơn:
betweenSmallerAndCurrent[i] = -1 or
input[smaller[i]] < input[betweenSmallerAndCurrent[i]] < input[value[i]] and
smaller[i] < betweenSmallerAndCurrent[i] < value[i]
Việc xây dựng nên dễ dàng hơn.
Bạn chỉ cần trả lại chỉ mục i
trong đó betweenSmallerAndCurrent[i]
, smaller[betweenSmallerAndCurrent[i]]
và greater[i]
đều được khởi tạo. Lưu ý rằng chúng tôi không thể chỉ cần kiểm tra smaller[i]
vì chúng tôi có thể có một cái gì đó như [2,3,1,4,5]
, trong trường hợp này, khi chúng tôi nhận được 4
, giá trị nhỏ nhất thứ hai 3
trước giá trị nhỏ nhất hiện tại 1
.
Ví dụ:
Indices: 0 1 2 3 4 5 6 7
Input: 12 11 10 5 6 2 9 30
smaller: -1 -1 -1 -1 3 -1 5 5
betweenSmallerAndCurrent:
-1 -1 -1 -1 -1 -1 4 4
greater: 7 7 7 7 7 7 7 -1
Chỉ số duy nhất với tất cả các giá trị khởi tạo là 6 (đầu vào giá trị 9). đang
Java: (không thử nghiệm rộng rãi)
void find4Numbers(int arr[], int n)
{
int max = n-1; //Index of maximum element from right side
int min = 0, second = -1; //Index of minimum element from left side
int i;
// Create an array that will store index of a smaller
// element on left side. If there is no smaller element
// on left side, then smaller[i] will be -1.
int[] smaller = new int[n];
int[] betweenSmallerAndCurrent = new int[n];
smaller[0] = -1; // first entry will always be -1
betweenSmallerAndCurrent[0] = -1;
for (i = 1; i < n; i++)
{
if (arr[i] <= arr[min])
{
min = i;
smaller[i] = -1;
betweenSmallerAndCurrent[i] = -1;
}
else
{
smaller[i] = min;
if (second != -1 && arr[second] < arr[i])
betweenSmallerAndCurrent[i] = second;
else
betweenSmallerAndCurrent[i] = -1;
if (second == -1 || arr[i] < arr[second])
second = i;
}
}
// Create another array that will store index of a
// greater element on right side. If there is no greater
// element on right side, then greater[i] will be -1.
int[] greater = new int[n];
greater[n-1] = -1; // last entry will always be -1
for (i = n-2; i >= 0; i--)
{
if (arr[i] >= arr[max])
{
max = i;
greater[i] = -1;
}
else
greater[i] = max;
}
// Make sure they're right
System.out.println(Arrays.toString(smaller));
System.out.println(Arrays.toString(betweenSmallerAndCurrent));
System.out.println(Arrays.toString(greater));
// Now find a number which has both a greater number on
// right side and smaller number on left side
for (i = 0; i < n; i++)
{
if (betweenSmallerAndCurrent[i] != -1 && smaller[betweenSmallerAndCurrent[i]] != -1 && greater[i] != -1)
{
System.out.printf("%d %d %d %d\n",
arr[smaller[betweenSmallerAndCurrent[i]]],
arr[betweenSmallerAndCurrent[i]],
arr[i],
arr[greater[i]]);
return;
}
}
// If we reach number, then there are no such 3 numbers
System.out.println("No such triplet found");
}
Bạn có thể nhận thấy rằng những thay đổi mã chính từ this, ngoài C để chuyển đổi Java và khởi tạo thêm, nằm trong vòng lặp mà thiết lập smaller
. Mã nên khá dễ hiểu - hãy thử dịch nó thành các từ nếu bạn gặp rắc rối.
Test.
Có thể không có sự gia tăng về sau. Xem xét trình tự 10 9 8 7 6 5 4 3 2 1, nó không có các chuỗi tăng [không tầm thường] tăng lên –
Mặc dù Erdős và Szekeres đã chứng minh rằng có độ dài chuỗi đơn điệu (tăng hoặc giảm) ít nhất là sqrt (n). –
@colonelPanic bạn có thể giả định rằng có tồn tại một chuỗi như vậy. –