1月12日晚,大量携程员工突然收到一条措辞正式的离职通知短信,内容以“XX你好,感谢一路相伴”开头。此次乌龙事件源于内部沟通软件trappal下线,在关停关联手机号绑定功能时,工作人员未提前关闭系统预设的短信提醒,该事件还一度登顶微博热搜榜。
事件发生后,携程通过内部渠道向员工说明,这是一次系统测试阶段的乌龙事件,不存在全员离职计划,并向受影响员工致歉。网友们对此议论纷纷,有人调侃这是“巨大的草台班子”,还有人评论说“人怎么可以捅这么大的篓子”。更有网友认为携程在免费做宣传,称其为“营销鬼才”。 ![]()
![]()
![]()
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第1458题:两个子序列的最大点积,难度是困难。
给你两个数组 nums1 和 nums2 。请你返回 nums1 和 nums2 中两个长度相同的非空子序列的最大点积。 数组的非空子序列是通过删除原数组中某些元素(可能一个也不删除)后剩余数字组成的序列,但不能改变数字间相对顺序。比方说,[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] 。
它们的点积为 (2*3 + (-2)*(-6)) = 18 。
示例2:
输入:nums1 = [3,-2], nums2 = [2,-6,7]
输出:21
解释:从 nums1 中得到子序列 [3] ,从 nums2 中得到子序列 [7] 。
它们的点积为 (3*7) = 21 。
1 <= nums1.length, nums2.length <= 500
-1000 <= nums1[i], nums2[i] <= 1000
问题分析
这题说的是从两个数组中分别找出两个长度一样的子序列,计算他们的最大点集,实际上这题是求最长公共子序列的翻版,我们完全可以按照求最长公共子序列的方式来解这道题,也就是使用动态规划。 定义dp[i][j]表示nums1的前 i 个字符和nums2的前 j 个字符得到的最大点集,那么最终结果就是dp[m][n],其中m,n分别是nums1和nums2的长度,那么递推公式是什么呢? 当计算dp[i][j]的时候,我们可以同时选择数字nums1[i]和数字nums2[j],那么递推公式就是dp[i][j]=dp[i-1][j-1]+cur,其中cur是数字nums1[i]和数字nums2[j]的乘积。 也可以只选择数字nums1[i],不选择数字nums2[j],那么递推公式就是dp[i][j]=dp[i][j-1]。 也可以只选择数字nums2[j],不选择数字nums1[i],那么递推公式就是dp[i][j]=dp[i-1][j]。 也可以数字nums1[i]和数字nums2[j]都不选择,那么递推公式就是dp[i][j]=dp[i-1][j-1],因为前面的dp[i][j-1]和dp[i-1][j-1]对应的状态已经包含了dp[i-1][j-1],所以这个我们可以不写。 其实这里还一种,就是前面的我们都不选,只选择当前的两个数字的乘积cur,因为题中说的是非空的子序列,所以每一个数组最少要选择一个元素。 以上几种情况我们只需要取最大值即可。 JAVA:
public int maxDotProduct(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
int[][] dp = newint[m + 1][n + 1];
for (int[] d : dp)
Arrays.fill(d, Integer.MIN_VALUE / 2);// 初始化一个比较大的负数
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
int cur = nums1[i - 1] * nums2[j - 1];
// 递推公式
dp[i][j] = Math.max(cur, Math.max(dp[i - 1][j - 1] + cur,
Math.max(dp[i - 1][j], dp[i][j - 1])));
}
}
return dp[m][n];
}
C++:public:
int maxDotProduct(vector &nums1, vector &nums2) {
int m = nums1.size(), n = nums2.size();
// 初始化一个比较大的负数
vector> dp(m + 1, vector(n + 1, INT_MIN / 2));
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
int cur = nums1[i - 1] * nums2[j - 1];
// 递推公式
dp[i][j] = max(cur, max(dp[i - 1][j - 1] + cur,
max(dp[i - 1][j], dp[i][j - 1])));
}
}
return dp[m][n];
}
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.