Max Dot Product of Two Subsequences

Hard
Watch on YouTube ↗

Solution

/******Recursive with Memoization******* */
class Solution {
    int nums1[];
    int nums2[];
    Integer dp[][];
    public int maxDotProduct(int[] nums1, int[] nums2) {
        this.nums1 = nums1;
        this.nums2 = nums2;
        dp = new Integer[nums1.length][nums2.length];
        return helper(0,0); 
    }

    int helper(int i, int j) {
        // base case
        if(i>=nums1.length || j>=nums2.length) {
            return Integer.MIN_VALUE;
        }
        if(dp[i][j]!=null) {
            return dp[i][j];
        }
        int skip1 = helper(i+1, j);
        int skip2 = helper(i, j+1);
        int take = nums1[i]*nums2[j] + Math.max(0, helper(i+1, j+1));

        return dp[i][j] = Math.max(Math.max(skip1, skip2), take);
    }

    
}
/**************Iterative Dp******** */
class Solution {
    public int maxDotProduct(int[] nums1, int[] nums2) {
        int n = nums1.length;
        int m = nums2.length;

        int[][] dp = new int[n + 1][m + 1];

        // initialize base cases
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                dp[i][j] = Integer.MIN_VALUE;
            }
        }

        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                int take = nums1[i] * nums2[j]
                         + Math.max(0, dp[i + 1][j + 1]);

                int skip1 = dp[i + 1][j];
                int skip2 = dp[i][j + 1];

                dp[i][j] = Math.max(take, Math.max(skip1, skip2));
            }
        }

        return dp[0][0];
    }
}