动态规划-LCS-LIS-离散化-1748. 最长公共子序列III
2020-04-04 12:18:00
问题描述:
给出1-n的两个排列P1和P2,求它们的最长公共子序列。请将复杂度控制在O(nlogn)。
样例
样例 1:
输入:[3,2,1,4,5],[1,2,3,4,5] 输出:3 解释:最长公共子序列为[1,4,5]。
样例 2:
输入:[6,9,4,2,8,1,3,5,7],[8,1,2,4,5,3,7,9,6] 输出:4 解释:最长公共子序列为[8,1,3,7]。
问题求解:
naive的LCS是O(n ^ 2)在本题中会卡时限。可以通过离散化的方式将原问题转为LIS问题,就可以在O(nlogn)求解。
时间复杂度:O(nlogn)
public int longestCommonSubsequenceIII(int[] A, int[] B) {
// Write your code here
int n = A.length;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < n; i++) map.put(A[i], i);
int[] nums = new int[n];
for (int i = 0; i < n; i++) nums[i] = map.get(B[i]);
return helper(nums);
}
private int helper(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp, Integer.MAX_VALUE);
for (int num : nums) {
int idx = ub(dp, num);
dp[idx] = num;
}
return ub(dp, Integer.MAX_VALUE);
}
private int ub(int[] nums, int num) {
int l = -1;
int r = nums.length;
while (r - l > 1) {
int mid = l + (r - l) / 2;
if (nums[mid] >= num) r = mid;
else l = mid;
}
return r;
}

浙公网安备 33010602011771号