手机搭建网站软件,wordpress注册登录插件,个人网站建设服务,朝阳住房和城乡建设官方网站题目
题目 给你两个数组 nums1 和 nums2 。
请你返回 nums1 和 nums2 中两个长度相同的 非空 子序列的最大点积。
数组的非空子序列是通过删除原数组中某些元素#xff08;可能一个也不删除#xff09;后剩余数字组成的序列#xff0c;但不能改变数字间相对顺序。比方说可能一个也不删除后剩余数字组成的序列但不能改变数字间相对顺序。比方说[2,3,5] 是 [1,2,3,4,5] 的一个子序列而 [1,5,3] 不是。
示例 1
输入nums1 [2,1,-2,5], nums2 [3,0,-6] 输出18 解释从 nums1 中得到子序列 [2,-2] 从 nums2 中得到子序列 [3,-6] 。 它们的点积为 (23 (-2)(-6)) 18 。 示例 2
输入nums1 [3,-2], nums2 [2,-6,7] 输出21 解释从 nums1 中得到子序列 [3] 从 nums2 中得到子序列 [7] 。 它们的点积为 (3*7) 21 。 示例 3
输入nums1 [-1,-1], nums2 [1,1] 输出-1 解释从 nums1 中得到子序列 [-1] 从 nums2 中得到子序列 [1] 。 它们的点积为 -1 。
提示
1 nums1.length, nums2.length 500 -1000 nums1[i], nums2[i] 100
题解
记忆化搜索
class Solution {private int[] nums1, nums2;private int[][] cache;private int mk Integer.MIN_VALUE;public int maxDotProduct(int[] nums1, int[] nums2) {this.nums1 nums1;this.nums2 nums2;int n1 nums1.length, n2 nums2.length;cache new int[n1][n2];for (int i 0; i n1; i) {Arrays.fill(cache[i],-1);}//答案可能存在负数return dfs(n1 - 1, n2 - 1) 0 ? dfs(n1 - 1, n2 - 1) : mk;}public int dfs(int i, int j) {if (i 0 || j 0) {return 0;}if (cache[i][j] ! -1) {return cache[i][j];}int k nums1[i] * nums2[j];mk Math.max(mk, k);return cache[i][j] Math.max(Math.max(dfs(i - 1, j), dfs(i, j - 1)), dfs(i - 1, j - 1) k);}
}递推
class Solution {public int maxDotProduct(int[] nums1, int[] nums2) {int n1 nums1.length, n2 nums2.length;int mk Integer.MIN_VALUE;int[][] f new int[n1 1][n2 1];for (int i 0; i n1; i) {for (int j 0; j n2; j) {int k nums1[i] * nums2[j];mk Math.max(k, mk);f[i 1][j 1] Math.max(Math.max(f[i][j 1], f[i 1][j]), f[i][j] k);}}return f[n1][n2] 0 ? f[n1][n2] : mk;}
}空间优化
class Solution {public int maxDotProduct(int[] nums1, int[] nums2) {int n2 nums2.length;int mk Integer.MIN_VALUE;int[] f new int[n2 1];for (int x : nums1) {int pre f[0];for (int j 0; j n2; j) {int temp f[j 1];int k x * nums2[j];mk Math.max(k, mk);f[j 1] Math.max(Math.max(f[j 1], f[j]), pre k);pre temp;}}return f[n2] 0 ? f[n2] : mk;}
}