רצף {X1 X2 .. Xn} הוא רצף מתחלף אם האלמנטים שלו עומדים באחד מהקשרים הבאים:
X1< X2 >X3< X4 >X5< …. xn or
X1 > X2< X3 >X4< X5 >…. xn
דוגמאות:
תרגול מומלץ רצף המשנה הארוך ביותר לסירוגין נסה את זה!קֶלֶט: arr[] = {1 5 4}
תְפוּקָה: 3
הֶסבֵּר: המערכים השלמים הם בצורת x1< x2 >x3קֶלֶט: arr[] = {10 22 9 33 49 50 31 60}
תְפוּקָה: 6
הֶסבֵּר: המשנה {10 22 9 33 31 60} או
{10 22 9 49 31 60} או {10 22 9 50 31 60}
הם הרצף הארוך ביותר באורך 6
פֶּתֶק: בעיה זו היא הרחבה של בעיית המשנה המתגברת ביותר אבל דורש יותר חשיבה למציאת תכונת תשתית אופטימלית בזה
רצף המשנה הארוך ביותר לסירוגין באמצעות תכנות דינמי :
כדי לפתור את הבעיה בצע את הרעיון הבא:
נפתור בעיה זו על ידי שיטת תכנות דינמית שכן יש לה תת-מבנה אופטימלי ותתי-בעיות חופפות
10 1 מיליון
בצע את השלבים הבאים כדי לפתור את הבעיה:
- תנו ל-A לקבל מערך באורך N
- אנו מגדירים מערך דו-ממדי las[n][2] כך ש-las[i][0] מכיל את רצף המשנה המתחלף הארוך ביותר המסתיים באינדקס i והאלמנט האחרון גדול מהאלמנט הקודם שלו
- las[i][1] מכיל את רצף המשנה המתחלף הארוך ביותר המסתיים באינדקס i והאלמנט האחרון קטן מהאלמנט הקודם שלו, אז יש לנו את יחס החזרה הבא ביניהם
לאס[i][0] = אורך הרצף המתחלף הארוך ביותר
המסתיים באינדקס i והאלמנט האחרון גדול יותר
מהאלמנט הקודם שלוה[i][1] = אורך הרצף המתחלף הארוך ביותר
מסתיים באינדקס i והאלמנט האחרון קטן יותר
מהאלמנט הקודם שלוניסוח רקורסיבי:
las[i][0] = max (las[i][0] las[j][1] + 1);
לכל j< i and A[j] < A[i]las[i][1] = max (las[i][1] las[j][0] + 1);
לכל j< i and A[j] >א[i]בחר sql ממספר טבלאות
- יחס החזרה הראשון מבוסס על העובדה שאם אנחנו במיקום i והאלמנט הזה צריך להיות גדול מהאלמנט הקודם שלו אז כדי שהרצף הזה (עד i) יהיה גדול יותר ננסה לבחור אלמנט j (< i) such that A[j] < A[i] i.e. A[j] can become A[i]’s previous element and las[j][1] + 1 is bigger than las[i][0] then we will update las[i][0].
- זכרו שבחרנו ב-las[j][1] + 1 לא las[j][0] + 1 כדי לספק את המאפיין החלופי כי ב-las[j][0] האלמנט האחרון גדול מהקודם שלו ו-A[i] גדול מ-A[j] מה שישבור את התכונה החלופית אם נעדכן. אז העובדה שלמעלה גוזרת את יחס החזרה הראשון, ניתן להעלות טיעון דומה גם ליחס החזרה השני.
להלן יישום הגישה לעיל:
C++// C++ program to find longest alternating // subsequence in an array #include using namespace std; // Function to return max of two numbers int max(int a int b) { return (a > b) ? a : b; } // Function to return longest alternating // subsequence length int zzis(int arr[] int n) { /*las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element */ int las[n][2]; // Initialize all values from 1 for (int i = 0; i < n; i++) las[i][0] = las[i][1] = 1; // Initialize result int res = 1; // Compute values in bottom up manner for (int i = 1; i < n; i++) { // Consider all elements as // previous of arr[i] for (int j = 0; j < i; j++) { // If arr[i] is greater then // check with las[j][1] if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) las[i][0] = las[j][1] + 1; // If arr[i] is smaller then // check with las[j][0] if (arr[j] > arr[i] && las[i][1] < las[j][0] + 1) las[i][1] = las[j][0] + 1; } // Pick maximum of both values at index i if (res < max(las[i][0] las[i][1])) res = max(las[i][0] las[i][1]); } return res; } // Driver code int main() { int arr[] = { 10 22 9 33 49 50 31 60 }; int n = sizeof(arr) / sizeof(arr[0]); cout << 'Length of Longest alternating ' << 'subsequence is ' << zzis(arr n); return 0; } // This code is contributed by shivanisinghss2110
C // C program to find longest alternating subsequence in // an array #include #include // function to return max of two numbers int max(int a int b) { return (a > b) ? a : b; } // Function to return longest alternating subsequence length int zzis(int arr[] int n) { /*las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element */ int las[n][2]; /* Initialize all values from 1 */ for (int i = 0; i < n; i++) las[i][0] = las[i][1] = 1; int res = 1; // Initialize result /* Compute values in bottom up manner */ for (int i = 1; i < n; i++) { // Consider all elements as previous of arr[i] for (int j = 0; j < i; j++) { // If arr[i] is greater then check with // las[j][1] if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) las[i][0] = las[j][1] + 1; // If arr[i] is smaller then check with // las[j][0] if (arr[j] > arr[i] && las[i][1] < las[j][0] + 1) las[i][1] = las[j][0] + 1; } /* Pick maximum of both values at index i */ if (res < max(las[i][0] las[i][1])) res = max(las[i][0] las[i][1]); } return res; } /* Driver code */ int main() { int arr[] = { 10 22 9 33 49 50 31 60 }; int n = sizeof(arr) / sizeof(arr[0]); printf( 'Length of Longest alternating subsequence is %dn' zzis(arr n)); return 0; }
Java // Java program to find longest // alternating subsequence in an array import java.io.*; class GFG { // Function to return longest // alternating subsequence length static int zzis(int arr[] int n) { /*las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element */ int las[][] = new int[n][2]; /* Initialize all values from 1 */ for (int i = 0; i < n; i++) las[i][0] = las[i][1] = 1; int res = 1; // Initialize result /* Compute values in bottom up manner */ for (int i = 1; i < n; i++) { // Consider all elements as // previous of arr[i] for (int j = 0; j < i; j++) { // If arr[i] is greater then // check with las[j][1] if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) las[i][0] = las[j][1] + 1; // If arr[i] is smaller then // check with las[j][0] if (arr[j] > arr[i] && las[i][1] < las[j][0] + 1) las[i][1] = las[j][0] + 1; } /* Pick maximum of both values at index i */ if (res < Math.max(las[i][0] las[i][1])) res = Math.max(las[i][0] las[i][1]); } return res; } /* Driver code*/ public static void main(String[] args) { int arr[] = { 10 22 9 33 49 50 31 60 }; int n = arr.length; System.out.println('Length of Longest ' + 'alternating subsequence is ' + zzis(arr n)); } } // This code is contributed by Prerna Saini
Python3 # Python3 program to find longest # alternating subsequence in an array # Function to return max of two numbers def Max(a b): if a > b: return a else: return b # Function to return longest alternating # subsequence length def zzis(arr n): '''las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element''' las = [[0 for i in range(2)] for j in range(n)] # Initialize all values from 1 for i in range(n): las[i][0] las[i][1] = 1 1 # Initialize result res = 1 # Compute values in bottom up manner for i in range(1 n): # Consider all elements as # previous of arr[i] for j in range(0 i): # If arr[i] is greater then # check with las[j][1] if (arr[j] < arr[i] and las[i][0] < las[j][1] + 1): las[i][0] = las[j][1] + 1 # If arr[i] is smaller then # check with las[j][0] if(arr[j] > arr[i] and las[i][1] < las[j][0] + 1): las[i][1] = las[j][0] + 1 # Pick maximum of both values at index i if (res < max(las[i][0] las[i][1])): res = max(las[i][0] las[i][1]) return res # Driver Code arr = [10 22 9 33 49 50 31 60] n = len(arr) print('Length of Longest alternating subsequence is' zzis(arr n)) # This code is contributed by divyesh072019
C# // C# program to find longest // alternating subsequence // in an array using System; class GFG { // Function to return longest // alternating subsequence length static int zzis(int[] arr int n) { /*las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element */ int[ ] las = new int[n 2]; /* Initialize all values from 1 */ for (int i = 0; i < n; i++) las[i 0] = las[i 1] = 1; // Initialize result int res = 1; /* Compute values in bottom up manner */ for (int i = 1; i < n; i++) { // Consider all elements as // previous of arr[i] for (int j = 0; j < i; j++) { // If arr[i] is greater then // check with las[j][1] if (arr[j] < arr[i] && las[i 0] < las[j 1] + 1) las[i 0] = las[j 1] + 1; // If arr[i] is smaller then // check with las[j][0] if (arr[j] > arr[i] && las[i 1] < las[j 0] + 1) las[i 1] = las[j 0] + 1; } /* Pick maximum of both values at index i */ if (res < Math.Max(las[i 0] las[i 1])) res = Math.Max(las[i 0] las[i 1]); } return res; } // Driver Code public static void Main() { int[] arr = { 10 22 9 33 49 50 31 60 }; int n = arr.Length; Console.WriteLine('Length of Longest ' + 'alternating subsequence is ' + zzis(arr n)); } } // This code is contributed by anuj_67.
PHP // PHP program to find longest // alternating subsequence in // an array // Function to return longest // alternating subsequence length function zzis($arr $n) { /*las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element */ $las = array(array()); /* Initialize all values from 1 */ for ( $i = 0; $i < $n; $i++) $las[$i][0] = $las[$i][1] = 1; $res = 1; // Initialize result /* Compute values in bottom up manner */ for ( $i = 1; $i < $n; $i++) { // Consider all elements // as previous of arr[i] for ($j = 0; $j < $i; $j++) { // If arr[i] is greater then // check with las[j][1] if ($arr[$j] < $arr[$i] and $las[$i][0] < $las[$j][1] + 1) $las[$i][0] = $las[$j][1] + 1; // If arr[i] is smaller then // check with las[j][0] if($arr[$j] > $arr[$i] and $las[$i][1] < $las[$j][0] + 1) $las[$i][1] = $las[$j][0] + 1; } /* Pick maximum of both values at index i */ if ($res < max($las[$i][0] $las[$i][1])) $res = max($las[$i][0] $las[$i][1]); } return $res; } // Driver Code $arr = array(10 22 9 33 49 50 31 60 ); $n = count($arr); echo 'Length of Longest alternating ' . 'subsequence is ' zzis($arr $n) ; // This code is contributed by anuj_67. ?> JavaScript <script> // Javascript program to find longest // alternating subsequence in an array // Function to return longest // alternating subsequence length function zzis(arr n) { /*las[i][0] = Length of the longest alternating subsequence ending at index i and last element is greater than its previous element las[i][1] = Length of the longest alternating subsequence ending at index i and last element is smaller than its previous element */ let las = new Array(n); for (let i = 0; i < n; i++) { las[i] = new Array(2); for (let j = 0; j < 2; j++) { las[i][j] = 0; } } /* Initialize all values from 1 */ for (let i = 0; i < n; i++) las[i][0] = las[i][1] = 1; let res = 1; // Initialize result /* Compute values in bottom up manner */ for (let i = 1; i < n; i++) { // Consider all elements as // previous of arr[i] for (let j = 0; j < i; j++) { // If arr[i] is greater then // check with las[j][1] if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) las[i][0] = las[j][1] + 1; // If arr[i] is smaller then // check with las[j][0] if( arr[j] > arr[i] && las[i][1] < las[j][0] + 1) las[i][1] = las[j][0] + 1; } /* Pick maximum of both values at index i */ if (res < Math.max(las[i][0] las[i][1])) res = Math.max(las[i][0] las[i][1]); } return res; } let arr = [ 10 22 9 33 49 50 31 60 ]; let n = arr.length; document.write('Length of Longest '+ 'alternating subsequence is ' + zzis(arr n)); // This code is contributed by rameshtravel07. </script>
תְפוּקָה
Length of Longest alternating subsequence is 6
מורכבות זמן: עַל2)
מרחב עזר: O(N) מאז נלקח N רווח נוסף
גישה יעילה: כדי לפתור את הבעיה בצע את הרעיון הבא:
בגישה שלעיל בכל רגע אנו עוקבים אחר שני ערכים (אורך רצף המשנה המתחלף הארוך ביותר המסתיים באינדקס i והאלמנט האחרון קטן או גדול מהאלמנט הקודם) עבור כל אלמנט במערך. כדי לייעל את המרחב אנחנו צריכים רק לאחסן שני משתנים עבור אלמנט בכל אינדקס i
inc = אורך הרצף החלופי הארוך ביותר עד כה, כאשר הערך הנוכחי גדול מהערך הקודם שלו.
dec = אורך רצף המשנה החלופי הארוך ביותר עד כה, כאשר הערך הנוכחי קטן מהערך הקודם שלו.
החלק המסובך בגישה זו הוא לעדכן את שני הערכים הללו.יש להגדיל את 'inc' אם ורק אם האלמנט האחרון ברצף החלופי היה קטן יותר מהאלמנט הקודם שלו.
יש להגדיל את 'dec' אם ורק אם האלמנט האחרון ברצף החלופי היה גדול מהאלמנט הקודם שלו.
בצע את השלבים הבאים כדי לפתור את הבעיה:
- הכריז על שני מספרים שלמים inc ו-dec שווים לאחד
- הפעל לולאה עבור i [1 N-1]
- אם arr[i] גדול מהאלמנט הקודם אז הגדר את inc שווה ל-dec + 1
- אחרת אם arr[i] קטן מהאלמנט הקודם, הגדר את dec שווה ל-inc + 1
- החזר מקסימום של עלייה וירידה
להלן יישום הגישה לעיל:
C++// C++ program for above approach #include using namespace std; // Function for finding // longest alternating // subsequence int LAS(int arr[] int n) { // 'inc' and 'dec' initialized as 1 // as single element is still LAS int inc = 1; int dec = 1; // Iterate from second element for (int i = 1; i < n; i++) { if (arr[i] > arr[i - 1]) { // 'inc' changes if 'dec' // changes inc = dec + 1; } else if (arr[i] < arr[i - 1]) { // 'dec' changes if 'inc' // changes dec = inc + 1; } } // Return the maximum length return max(inc dec); } // Driver Code int main() { int arr[] = { 10 22 9 33 49 50 31 60 }; int n = sizeof(arr) / sizeof(arr[0]); // Function Call cout << LAS(arr n) << endl; return 0; }
Java // Java Program for above approach public class GFG { // Function for finding // longest alternating // subsequence static int LAS(int[] arr int n) { // 'inc' and 'dec' initialized as 1 // as single element is still LAS int inc = 1; int dec = 1; // Iterate from second element for (int i = 1; i < n; i++) { if (arr[i] > arr[i - 1]) { // 'inc' changes if 'dec' // changes inc = dec + 1; } else if (arr[i] < arr[i - 1]) { // 'dec' changes if 'inc' // changes dec = inc + 1; } } // Return the maximum length return Math.max(inc dec); } // Driver Code public static void main(String[] args) { int[] arr = { 10 22 9 33 49 50 31 60 }; int n = arr.length; // Function Call System.out.println(LAS(arr n)); } }
Python3 # Python3 program for above approach def LAS(arr n): # 'inc' and 'dec' initialized as 1 # as single element is still LAS inc = 1 dec = 1 # Iterate from second element for i in range(1 n): if (arr[i] > arr[i-1]): # 'inc' changes if 'dec' # changes inc = dec + 1 elif (arr[i] < arr[i-1]): # 'dec' changes if 'inc' # changes dec = inc + 1 # Return the maximum length return max(inc dec) # Driver Code if __name__ == '__main__': arr = [10 22 9 33 49 50 31 60] n = len(arr) # Function Call print(LAS(arr n))
C# // C# program for above approach using System; class GFG { // Function for finding // longest alternating // subsequence static int LAS(int[] arr int n) { // 'inc' and 'dec' initialized as 1 // as single element is still LAS int inc = 1; int dec = 1; // Iterate from second element for (int i = 1; i < n; i++) { if (arr[i] > arr[i - 1]) { // 'inc' changes if 'dec' // changes inc = dec + 1; } else if (arr[i] < arr[i - 1]) { // 'dec' changes if 'inc' // changes dec = inc + 1; } } // Return the maximum length return Math.Max(inc dec); } // Driver code static void Main() { int[] arr = { 10 22 9 33 49 50 31 60 }; int n = arr.Length; // Function Call Console.WriteLine(LAS(arr n)); } } // This code is contributed by divyeshrabadiya07
JavaScript <script> // Javascript program for above approach // Function for finding // longest alternating // subsequence function LAS(arr n) { // 'inc' and 'dec' initialized as 1 // as single element is still LAS let inc = 1; let dec = 1; // Iterate from second element for (let i = 1; i < n; i++) { if (arr[i] > arr[i - 1]) { // 'inc' changes if 'dec' // changes inc = dec + 1; } else if (arr[i] < arr[i - 1]) { // 'dec' changes if 'inc' // changes dec = inc + 1; } } // Return the maximum length return Math.max(inc dec); } let arr = [ 10 22 9 33 49 50 31 60 ]; let n = arr.length; // Function Call document.write(LAS(arr n)); // This code is contributed by mukesh07. </script>
תְפוּקָה:
מכיל פיתון
6
מורכבות זמן: עַל)
מרחב עזר: O(1)
צור חידון