logically swap or not swap recursively O(n) a solution explanation you can understand
At each index, we compare the results after swapping and not swapping A and B.\n\nwe need to know from the previous step, if A and B are swapped, if so previous
**At each index, we compare the results after swapping and not swapping A and B.**\n\n**we need to know from the previous step, if A and B are swapped, if so `previous a` becomes `previous b`, and `previous b` becomes `previous a`**\n\n**when `current a > previous b` AND `current b > previous a`, swap action is possible, caldulate the result of swap.**\n\n**when `current a <= previous a` OR `current b <= previous b`, must swap, return the result of swap above**\n\n**when swap is not a must, return min(swap, notSwap)**\n\n```javascript\nfunction rc (a, b, index = 0, previousOneSwapped = false) {\n    if (index >= a.length) return 0;\n\n\t// if from the previous step, a and b are swapped, previous a becomes previous b and previous b becomes previous a\n    const [previousA, previousB] = previousOneSwapped ? [b[index - 1], a[index - 1]] : [a[index - 1], b[index - 1]];\n       \n    const canSwap = index === 0 || a[index] > previousB && b[index] > previousA;\n    const mustSwap = index > 0 && (a[index] <= previousA || b[index] <= previousB);\n\n    let swapCurrent = Infinity;\n    if (canSwap) swapCurrent = 1 + rc(a, b, index + 1, true, memo);\n    if (mustSwap) return swapCurrent;\n\n    const doNotSwapCurrent = rc(a, b, index + 1, false, memo);\n    \n    return Math.min(swapCurrent, doNotSwapCurrent);\n}\n```\n\n**ADD MEMOISATION**\n\n```javascript\nfunction rc (a, b, index = 0, swapped = false, memo = {}) {\n    if (index >= a.length) return 0;\n\n    const memoKey = `${index},${swapped}`\n    if (memo[memoKey] !== undefined) return memo[memoKey]\n\n    const [previousA, previousB] = swapped ? [b[index - 1], a[index - 1]] : [a[index - 1], b[index - 1]];\n\n    let swapCurrent = Infinity;\n    if (index === 0 || a[index] > previousB && b[index] > previousA) swapCurrent = 1 + rc(a, b, index + 1, true, memo);\n    if (index > 0 && (a[index] <= previousA || b[index] <= previousB)) return memo[memoKey] = swapCurrent;\n    \n    return memo[memoKey] = Math.min(swapCurrent, rc(a, b, index + 1, false, memo));\n}\n```\n\n**Iterative DP**\n\n**The trcky bit of the iterative solution is the meaning of `a[i] > b[i - 1] && b[i] > a[i - 1]` and `a[i] > a[i - 1] && b[i] > b[i - 1]`** \n\nRead the code first, then come back here.\n\n**`a[i] > b[i - 1] && b[i] > a[i - 1]` means `current a > previous b && current b > previous a` when `noSwap[i - 1]` is used in calculation i.e. no swap from the previous step**\n\n**However, the same `a[i] > b[i - 1] && b[i] > a[i - 1]` means `current a > previous A && current b > previous B` when `swap[i - 1]` is used in calculation i.e. a and b have been swapped from the previous step**\n\n**Same logic for `a[i] > a[i - 1] && b[i] > b[i - 1]`**\n\n**it means `current a > previous a && current b > previous b` if `notSwap[i - 1]` used in calculation**\n**it means `current a > previous b && current b > previous a` if `swap[i - 1]` used in calculation**\n\n```javascript\nfunction dp (a, b) {\n    const swap = Array(a.length).fill(0);\n    const notSwap = Array(a.length).fill(0);\n    swap[0] = 1;\n    \n    for (let i = 1; i < a.length; i++) {\n        swap[i] = Infinity;\n        notSwap[i] = Infinity;\n        \n        if (a[i] > b[i - 1] && b[i] > a[i - 1]) {\n            swap[i] = Math.min(swap[i], 1 + notSwap[i - 1]);\n            notSwap[i] = Math.min(notSwap[i], swap[i - 1]);\n        }\n        \n        if (a[i] > a[i - 1] && b[i] > b[i - 1]) {\n            swap[i] = Math.min(swap[i], 1 + swap[i - 1]);\n            notSwap[i] = Math.min(notSwap[i], notSwap[i - 1]);\n        }\n    }\n    \n    return Math.min(swap[a.length - 1], notSwap[a.length - 1]);\n}\n```
[]