JavaScript程式查詢最長位元尼克子序列 | DP-15


我們將使用動態規劃在每個陣列中找到最長的位元尼克子序列。位元尼克子序列是指先遞增後遞減的序列。為了找到最長的位元尼克子序列,我們將使用兩步法。首先,我們將找到給定陣列中最長的遞增子序列,然後我們將找到給定陣列的反向中最長的遞減子序列。最後,我們將兩個子序列的長度相加,並減去 1 以排除中間的公共元素。

方法

位元尼克序列是指先遞增後遞減的序列。在給定陣列中找到最長位元尼克子序列的方法是使用動態規劃。

  • 初始化兩個陣列“inc”和“dec”,以儲存以每個索引結尾的最長遞增子序列的長度。

  • 遍歷陣列,使用先前索引處的值更新每個索引處的“inc”和“dec”的值。

  • 找到每個索引處“inc”和“dec”之和減一的最大值,因為這將給出包含該索引的最長位元尼克子序列的長度。

  • 將步驟 3 中找到的最大值作為最長位元尼克子序列的長度返回。

  • 要重建最長的位元尼克子序列,請使用“inc”和“dec”中的值從步驟 3 中給出最大值的索引回溯。

  • 將重建的序列作為最長的位元尼克子序列返回。

示例

這是一個使用動態規劃查詢最長位元尼克子序列的 JavaScript 程式的完整工作示例 -

function LBSLength(arr) {
   let n = arr.length;
   let lis = new Array(n).fill(1);
   let lds = new Array(n).fill(1);
     
   for (let i = 1; i < n; i++) {
      for (let j = 0; j < i; j++) {
         if (arr[i] > arr[j]) {
            lis[i] = Math.max(lis[i], lis[j] + 1);
         }
      }
   }
     
   for (let i = n - 2; i >= 0; i--) {
      for (let j = n - 1; j > i; j--) {
         if (arr[i] > arr[j]) {
            lds[i] = Math.max(lds[i], lds[j] + 1);
         }
      }
   }
     
   let maxLength = 0;
   for (let i = 0; i < n; i++) {
      maxLength = Math.max(maxLength, lis[i] + lds[i] - 1);
   }
    
   return maxLength;
}

const arr = [1, 7, 8, 11, 5, 2, 3];
console.log(LBSLength(arr)); 

解釋

  • 第一步是初始化兩個陣列,lislds,它們與輸入陣列 arr 的長度相同,並填充 1。lis 代表“最長遞增子序列”,lds 代表“最長遞減子序列”。

  • 下一步是計算lis[i],以arr[i]結尾的最長遞增子序列的長度。這是使用巢狀迴圈完成的,其中j的範圍從 0 到i-1。如果arr[i] > arr[j],我們將lis[i]更新為其當前值和lis[j] + 1中的最大值。

  • 下一步是計算lds[i],從arr[i]開始的最長遞減子序列的長度。這是使用巢狀迴圈完成的,其中j的範圍從n-1i+1。如果arr[i] > arr[j],我們將lds[i]更新為其當前值和lds[j] + 1中的最大值。

  • 最後,我們遍歷輸入陣列的n個元素,並找到lis[i] + lds[i] - 1的最大值,它表示以arr[i]結尾和開始的最長位元尼克子序列的長度。此值儲存在變數maxLength中。

  • 該函式返回maxLength,它是輸入陣列中最長位元尼克子序列的長度。

更新於:2023年3月15日

174 次檢視

開啟你的 職業生涯

透過完成課程獲得認證

開始
廣告

© . All rights reserved.