class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
// 初始化dp表
for (int i = 0; i < n; i++) {
dp[i] = 1;
}
// 填表
int ret = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
ret = Math.max(ret, dp[i]);
}
}
}
return ret;
}
}
class Solution {
public int wiggleMaxLength(int[] nums) {
int n = nums.length;
int[] f = new int[n];
int[] g = new int[n];
// 初始化
for (int i = 0; i < n; i++) {
f[i] = g[i] = 1;
}
// 填表
int ret = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
f[i] = Math.max(f[i], g[j] + 1);
}else if (nums[i] < nums[j]) {
g[i] = Math.max(g[i], f[j] + 1);
}
ret = Math.max(ret, Math.max(f[i], g[i]));
}
}
return ret;
}
}
class Solution {
public int findNumberOfLIS(int[] nums) {
int n = nums.length;
int[] len = new int[n];
int[] count = new int[n];
// 初始化
for (int i = 0; i < n; i++) {
len[i] = count[i] = 1;
}
// 填表, 并求最大个数
int max = len[0];
int ret = count[0];
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
if (len[j] + 1 == len[i]) {
count[i] += count[j];
} else if (len[j] + 1 > len[i]) {
len[i] = len[j] + 1;
count[i] = count[j];
}
}
}
if (len[i] == max) {
ret += count[i];
} else if (len[i] > max) {
max = len[i];
ret = count[i];
}
}
return ret;
}
}
class Solution {
public int longestSubsequence(int[] arr, int difference) {
// 建立hash表
int n = arr.length;
HashMap<Integer,Integer> hash = new HashMap<>();
// 初始化
hash.put(arr[0], 1);
// 填表
int ret = 1;
for (int i = 1; i < n; i++) {
int a = arr[i];
int b = a - difference;
int dp = hash.getOrDefault(b, 0) + 1;
hash.put(a, dp);
ret = Math.max(ret, dp);
}
return ret;
}
}
class Solution {
public int lenLongestFibSubseq(int[] arr) {
// 创建dp, hash表
int n = arr.length;
int[][] dp = new int[n][n];
HashMap<Integer, Integer> hash = new HashMap<>();
// 初始化dp, hash
for (int i = 0; i < n; i++) {
hash.put(arr[i], i);
for (int j = i + 1; j < n; j++) {
dp[i][j] = 2;
}
}
// 填表
int ret = 2;
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int a = arr[j] - arr[i];
if (hash.containsKey(a) && a < arr[i]) {
dp[i][j] = dp[hash.get(a)][i] + 1;
ret = Math.max(ret, dp[i][j]);
}
}
}
return ret == 2 ? 0 : ret;
}
}
class Solution {
public int longestArithSeqLength(int[] nums) {
// 建表
int n = nums.length;
int[][] dp = new int[n][n];
HashMap<Integer, Integer> hash = new HashMap<>();
// 初始化
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
dp[i][j] = 2;
}
}
hash.put(nums[0], 0);
// 填表
int ret = 2;
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int a = nums[i] * 2 - nums[j];
if (hash.containsKey(a)) {
dp[i][j] = dp[hash.get(a)][i] + 1;
ret = Math.max(ret, dp[i][j]);
}
}
hash.put(nums[i], i);
}
return ret;
}
}
class Solution {
public int numberOfArithmeticSlices(int[] nums) {
// 建表,初始化
int n = nums.length;
int[][] dp = new int[n][n];
Map<Long, List<Integer>> hash = new HashMap<>();
hash.put((long)nums[0], new ArrayList<>());
hash.get((long)nums[0]).add(0);
// 填表
int ret = 0;
for (int i = 1; i < n; i++) {
long b = (long)nums[i];
for (int j = i + 1; j < n; j++) {
long c = (long) nums[j];
long a = 2L * b - c;
// 这里a一定在b的左边, 不用多余判断
if (hash.containsKey(a)) {
for (int k : hash.get(a)) {
dp[i][j] += dp[k][i] + 1;
}
}
ret += dp[i][j];
}
if (!hash.containsKey(b)) {
hash.put(b, new ArrayList<>());
}
hash.get(b).add(i);
}
return ret;
}
}