ในปัญหานี้ เราได้รับอาร์เรย์ arr[] ซึ่งประกอบด้วยค่าจำนวนเต็ม n ค่า งานของเราคือค้นหาสิ่งที่เล็กกว่าตัวถัดไปจาก Greater ตัวถัดไปในอาร์เรย์
คำอธิบายปัญหา − เราจะพบองค์ประกอบที่มากกว่าองค์ประกอบปัจจุบันในอาร์เรย์ จากนั้นเราจะพบองค์ประกอบในอาร์เรย์ที่เล็กกว่าองค์ประกอบที่ใหญ่กว่านี้ และหากไม่มีองค์ประกอบที่เล็กกว่าหรือสูงกว่าถัดไปในอาร์เรย์ ให้คืนค่า -1
มาดูตัวอย่างเพื่อทำความเข้าใจปัญหากัน
อินพุต
arr[] = {4, 2, 8, 3, 9, 1} ผลลัพธ์
{3, 3, 1, 1, -1, -1} คำอธิบาย
อาร์เรย์ขององค์ประกอบที่มากกว่าถัดไป :{8, 8, 9, 9, -1, -1} เนื่องจาก 9 เป็นองค์ประกอบที่ใหญ่ที่สุดของอาร์เรย์ และ 1 เป็นองค์ประกอบสุดท้าย พวกมันจึงไม่มีองค์ประกอบที่ใหญ่กว่าถัดไป
อาร์เรย์ขององค์ประกอบที่ใหญ่กว่าถัดไป :{3, 3, 1, 1, -1, -1}
แนวทางการแก้ปัญหา
วิธีแก้ปัญหาอย่างง่ายคือการวนซ้ำบนอาร์เรย์และสำหรับแต่ละองค์ประกอบของอาร์เรย์
-
ค้นหาองค์ประกอบที่มากขึ้นถัดไปจากอาร์เรย์
-
ค้นหาองค์ประกอบที่เล็กกว่าองค์ประกอบที่ใหญ่กว่านี้ในอาร์เรย์ที่เหลือ
วิธีแก้ปัญหานี้เพื่อทำงาน แต่ความซับซ้อนของเวลาอยู่ในลำดับ O(n 2 )
ทางออกที่ดีกว่า ปัญหาสามารถใช้สแต็กและดัชนีขององค์ประกอบ
เราจะจัดเก็บดัชนีขององค์ประกอบที่มากขึ้นและเล็กถัดไปขององค์ประกอบปัจจุบันในอาร์เรย์ในชื่ออาร์เรย์สองชื่อ nextGreater[] และ nextSmaller[] ซึ่งหมายความว่าอาร์เรย์ nextGreater จะเก็บดัชนีขององค์ประกอบที่ใหญ่กว่าถัดไปขององค์ประกอบปัจจุบัน ตัวอย่างเช่น nextGreater[i] จะมีดัชนีขององค์ประกอบที่ใหญ่กว่าถัดไป ซึ่งจะเป็น arr[nextGreater[i]] และเช่นเดียวกันสำหรับ nextSmaller[] ด้วย
ดังนั้น เพื่อเข้าถึงองค์ประกอบที่เล็กที่สุดถัดไปขององค์ประกอบที่ใหญ่กว่าถัดไปของอาร์เรย์ เราจะพบองค์ประกอบเล็ก ๆ ของดัชนีต่อไปที่ nextGreater[i] สิ่งนี้จะให้ดัชนีขององค์ประกอบที่จำเป็นของเรา นั่นคือองค์ประกอบที่จำเป็นคือ arr[nextSmaller[nextGreater[i]]].
ในการค้นหาองค์ประกอบ เราจะใช้โครงสร้างข้อมูลสแต็ก ซึ่งจะเก็บองค์ประกอบของอาร์เรย์ย่อยที่เหลือ นี่คือการทำงานของฟังก์ชันเพื่อค้นหาองค์ประกอบที่มากขึ้น
-
=> เราจะสำรวจอาร์เรย์จากครั้งสุดท้าย i -> n-1 ถึง 0
-
=> หากสแต็กไม่ว่างเปล่าและด้านบนของสแต็กมีขนาดเล็กกว่าองค์ประกอบปัจจุบัน -> pop S ให้ทำสิ่งนี้จนกว่าจะพบองค์ประกอบที่มากกว่าหรือสแต็กว่างเปล่า
-
=> หาก stack ว่างเปล่า -> ไม่มีองค์ประกอบใดที่มากกว่านั้น ให้เก็บ -1,nextGreater[i] =-1
-
=> else -> องค์ประกอบที่ใหญ่กว่าถัดไปอยู่ที่ด้านบนสุดของ stack, เก็บด้านบนสุดของ stack, nextGreater[i] =stack.top()
-
=> ผลักองค์ประกอบปัจจุบันลงใน stack, stack.push()
วิธีเดียวกันนี้สามารถใช้เพื่อค้นหาองค์ประกอบที่เล็กกว่าถัดไปสำหรับองค์ประกอบปัจจุบันของอาร์เรย์ และเมื่อเราพบดัชนีของทั้งสองแล้ว เราสามารถใช้ดัชนีเหล่านี้เพื่อค้นหาองค์ประกอบที่จำเป็นจากอาร์เรย์ได้
โปรแกรมเพื่อแสดงการทำงานของโซลูชันของเรา
ตัวอย่าง
#include<bits/stdc++.h>
using namespace std;
void findNextGreater(int arr[], int n, int next[]) {
stack<int> nextGreater;
int i = n-1;
while(i >= 0) {
while (!nextGreater.empty() && arr[nextGreater.top()] <= arr[i] )
nextGreater.pop();
if (!nextGreater.empty())
next[i] = nextGreater.top();
else
next[i] = -1;
nextGreater.push(i);
i--;
}
}
void findNextSmaller(int arr[], int n, int next[]) {
stack<int> nextSmaller;
int i = n-1 ;
while(i >= 0){
while (!nextSmaller.empty() && arr[nextSmaller.top()] >= arr[i])
nextSmaller.pop();
if (!nextSmaller.empty())
next[i] = nextSmaller.top();
else
next[i] = -1;
nextSmaller.push(i);
i -- ;
}
}
void findNextSmallerofNextGreaterElemenetArray(int arr[], int n) {
int nextGreaterIndex[n];
int nextSmallerIndex[n];
findNextGreater(arr, n, nextGreaterIndex);
findNextSmaller(arr, n, nextSmallerIndex);
for (int i=0; i< n; i++){
if (nextGreaterIndex[i] != -1 && nextSmallerIndex[nextGreaterIndex[i]] != -1)
cout<<arr[nextSmallerIndex[nextGreaterIndex[i]]]<<"\t";
else
cout<<"-1"<<"\t";
}
}
int main(){
int arr[] = {4, 2, 8, 3, 9, 1};
int n = sizeof(arr)/sizeof(arr[0]);
cout<<"All next smaller of next greater elements of the array are ";
findNextSmallerofNextGreaterElemenetArray(arr, n);
return 0;
} ผลลัพธ์
All next smaller of next greater elements of the array are 3 3 1 1 -1 -1