最长等差子序列、最长定差子序列
const arr = [3, 3, 3, 3, 3];
function A1(A) {
const mp = new Map();
const n = A.length;
const dp = new Array(n).fill(0).map(() => new Array(n));
//dp含义是元素A[i]能和A[j]组合成多长的子序列
let res = 1;
mp.set(arr[0], 0);
for (let i = 1; i < n; i++) {
for (let j = i + 1; j < n; j++) {
const target = 2 * A[i] - A[j];
const pre = mp.get(target);
// pre若有则意味着有等差数列,那么就取出来那个值看看他的下标,找到那个位置的状态累计起来就行了
// 单纯的动态规划是难以得到等差数列区间之前那一个区间的状态的,所以要找到之前的那一个状态的位置
if (pre!==undefined) {
dp[i][j] = (dp[pre][i] || 1) + 1;
console.log(dp[pre][i]);
res = Math.max(res, dp[i][j]);
}
}
mp.set(A[i], i);// 放在这里有两个原因 第一个是预防前面的和这个元素一样,第二个是要选取前面的元素
}
}
A1(arr);
function A2(A, d) {
const mp = new Map();
const n = A.length;
let res = 0;
mp.set(A[0], 1);
for (let i = 1; i < n; i++) {
const t = mp.get(A[i] - d);
mp.set(A[i], (t || 0) + 1);
res = Math.max(res, mp.get(A[i]));
}
console.log(mp, res+1);
}
A2(arr, 0);
最长的斐波那契子序列的长度 和最长等差子序列逻辑一样
const arr = [1, 3, 7, 11, 12, 14, 18];
function A1(A) {
const mp = new Map();
const n = A.length;
const dp = new Array(n).fill(0).map(() => new Array(n));
//dp含义是元素A[i]能和A[j]组合成多长的斐波那契子列
let res = 1;
mp.set(arr[0], 0);
for (let i = 1; i < n; i++) {
for (let j = i + 1; j < n; j++) {
const target = A[j] - A[i];
const pre = mp.get(target);
if (pre !== undefined) {
dp[i][j] = (dp[pre][i] || 1) + 1;
res = Math.max(res, dp[i][j]);
}
}
mp.set(A[i], i);
}
return res+1;
}
console.log(A1(arr));
核心思想是:选取之前的状态来累计结果并判断,在选取之前的状态的时候我们要得到那个状态的下标,而我们在计算的时候只能得到之前那个状态的值,故要找到那个下标使用map,使用map的时候只能找之前的,所以在使用当前这个值后再放进去。