1131.绝对值表达式的最大值
给你两个长度相等的整数数组,返回下面表达式的最大值:
|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
其中下标 i,j 满足 0 <= i, j < arr1.length。
把Point(i, arr[i], arr[j])看作三位空间中的一个点,那么题目就是要求所有这些点中曼哈顿距离最远的两个点的距离。任意两个点的曼哈顿距离就等于:这两个点到8个角落的曼哈顿距离差绝对值的最大值.因此我们只需要针对每一个角落,找到最近、最远的点,然后计算他们的距离差 然后把八个角落结果再取最大就是我们要的结果。
class Solution {
public:const int MAX_N = 2e6;int CORNER[8][3] = {{0, 0, 0}, {0, 0, MAX_N}, {0, MAX_N, MAX_N}, {0, MAX_N, 0},{MAX_N, 0, 0}, {MAX_N, 0, MAX_N}, {MAX_N, MAX_N, MAX_N}, {MAX_N, MAX_N, 0}};int manhatten(int x1, int y1, int z1, int x2, int y2, int z2) {return abs(x1 - x2) + abs(y1 - y2) + abs(z1 - z2);}int maxAbsValExpr(vector& arr1, vector& arr2) {int N = arr1.size();vector > d(8, vector(N, 0));for (int i = 0; i < 8; ++i) {for (int j = 0; j < N; ++j) {d[i][j] = manhatten(j, arr1[j] + MAX_N / 2, arr2[j] + MAX_N / 2, CORNER[i][0], CORNER[i][1], CORNER[i][2]);}}int res = 0;for (int i = 0; i < 8; ++i) {int mx = *max_element(d[i].begin(), d[i].end());int mn = *min_element(d[i].begin(), d[i].end());res = max(res, mx - mn);}return res;}
};
1137.第 N 个泰波那契数
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
动态规划和矩阵快速幂解题均可
class Solution {
public:int tribonacci(int n) {if (n == 0) return 0;if (n == 1 || n == 2) return 1;int Now = 0, before1 = 1, before2 = 1, before3 = 0;int cnt = 2;while (cnt < n){cnt++;Now = before1 + before2 + before3;before3 = before2;before2 = before1;before1 = Now;}return Now;}
};
class Solution {
public:int tribonacci(int n) {if (n == 0) {return 0;}if (n <= 2) {return 1;}vector> q = {{1, 1, 1}, {1, 0, 0}, {0, 1, 0}};vector> res = pow(q, n);return res[0][2];}vector> pow(vector>& a, long n) {vector> ret = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};while (n > 0) {if ((n & 1) == 1) {ret = multiply(ret, a);}n >>= 1;a = multiply(a, a);}return ret;}vector> multiply(vector>& a, vector>& b) {vector> c(3, vector(3));for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];}}return c;}
};
1138.字母板上的路径
我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。返回指令序列,用最小的行动次数让答案和目标 target 相同。你可以返回任何达成目标的路径。
换算坐标然后查找
class Solution {
public:string alphabetBoardPath(string target) {int x = 0, y = 0;//当前坐标string s = "";for(char ch : target)//遍历目标字符串{int a = (ch - 97) / 5, b = (ch - 97) % 5;//得到目标字母的坐标while(a - x && !(a == 5 && x == 4))//进行上下移动,对z的情况特判{ //即需要跳到第六行时,最多跳到第五行if(a - x > 0){x++;s += 'D';}else{x--;s += 'U';}}while(b - y)//左右移动{if(b - y > 0){y++;s += 'R';}else{y--;s += 'L';}}if(a - x == 1)//对z情况特判的补充,补充上缺失的那一行的动作{x++;s += 'D';}s += '!';//到达目标坐标,添加!}return s;}
};
1139.最大的以 1 为边界的正方形
给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。
可以用dp求解,也可以用前缀和求解
class Solution {
public:int largest1BorderedSquare(vector>& grid) {int m = grid.size(), n = grid[0].size();vector> up(m + 1, vector(n + 1)); // 每列 连续 1 的个数vector> left(m + 1, vector(n + 1)); // 每行 连续 1 的个数int maxa = 0;for (int i = 1; i <= m; i ++) {for (int j = 1; j <= n; j ++) {if (grid[i - 1][j - 1] == 0) continue;// 计算 up leftup[i][j] = up[i - 1][j] + 1;left[i][j] = left[i][j - 1] + 1;// 判断正方形int t = min(up[i][j], left[i][j]); // 正方形下边和右边while (t > maxa) { // 判断正方形左边、上边if (up[i][j - t + 1] >= t && left[i - t + 1][j] >= t) {maxa = t;break;}t --; // 缩小正方形的边长 t 继续判断}}}return maxa * maxa;}
};
1140.石子游戏 II
爱丽丝和鲍勃继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]。游戏以谁手中的石子最多来决出胜负。假设爱丽丝和鲍勃都发挥出最佳水平,返回爱丽丝可以得到的最大数量的石头。
dp[i][j]表示剩余i个堆时,M=j,可以得到的最大石头数量(因为两个人都发挥最佳水平,所以不用区分是谁)
class Solution {
public:int stoneGameII(vector& piles) {int size = piles.size();vector> dp(size, vector(size, 0));int sum = 0;for (int i = size - 1; i >= 0; i--) {sum += piles[i];for (int M = 1; M <= size; M++) {if (i + 2 * M >= size) {dp[i][M - 1] = sum;continue;}for (int x = 1; x <= 2 * M; x++) {dp[i][M - 1] = max(dp[i][M - 1], sum - dp[i + x][max(x, M) - 1]);}}}return dp[0][0];}
};
1141 查询近30天活跃用户数
活动记录表:Activity
# Write your MySQL query statement below
SELECT activity_date AS day, COUNT(DISTINCT user_id) AS active_users
FROM Activity
WHERE activity_date BETWEEN DATE('2019-06-28') AND DATE('2019-07-27')
GROUP BY activity_date;
1143.最长公共子序列
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
典型动态规划问题,考虑二维数组dp[i][j]表示第一个数组到i,第二个数组到j的时候的最长公共子序列,然后遍历即可、
class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int m = text1.length(), n = text2.length();vector> dp(m + 1, vector(n + 1));for (int i = 1; i <= m; i++) {char c1 = text1.at(i - 1);for (int j = 1; j <= n; j++) {char c2 = text2.at(j - 1);if (c1 == c2) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[m][n];}
};