6101. 判断矩阵是否是一个 X 矩阵
如果一个正方形矩阵满足下述 全部 条件,则称之为一个 X 矩阵 :
矩阵对角线上的所有元素都 不是 0
矩阵中所有其他元素都是 0
给你一个大小为 n x n 的二维整数数组 grid ,表示一个正方形矩阵。如果 grid 是一个 X 矩阵 ,返回 true ;否则,返回 false 。
示例 1:
输入:grid = [[2,0,0,1],[0,3,1,0],[0,5,2,0],[4,0,0,2]]
输出:true
解释:矩阵如上图所示。
X 矩阵应该满足:绿色元素(对角线上)都不是 0 ,红色元素都是 0 。
因此,grid 是一个 X 矩阵。
示例 2:
输入:grid = [[5,7,0],[0,3,1],[0,5,0]]
输出:false
解释:矩阵如上图所示。
X 矩阵应该满足:绿色元素(对角线上)都不是 0 ,红色元素都是 0 。
因此,grid 不是一个 X 矩阵。
提示:
n == grid.length == grid[i].length
3 <= n <= 100
0 <= grid[i][j] <= 105
模拟题
遍历一遍,判断两条对角线元素是否非0,其他元素是否全是0
主对角线:i == j
副对角线:i + j == n - 1(因为下标是从 0 开始的)
class Solution {
public:
bool checkXMatrix(vector<vector<int>>& grid) {
int row = grid.size();
int col = grid[0].size();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (j == i || j + i == row - 1) {
if (grid[i][j] == 0) {
return false;
}
} else {
if (grid[i][j] != 0) {
return false;
}
}
}
}
return true;
}
};
6100. 统计放置房子的方式数
一条街道上共有 n * 2 个 地块 ,街道的两侧各有 n 个地块。每一边的地块都按从 1 到 n 编号。每个地块上都可以放置一所房子。
现要求街道同一侧不能存在两所房子相邻的情况,请你计算并返回放置房屋的方式数目。由于答案可能很大,需要对 109 + 7 取余后再返回。
注意,如果一所房子放置在这条街某一侧上的第 i 个地块,不影响在另一侧的第 i 个地块放置房子。
示例 1:
输入:n = 1
输出:4
解释:
可能的放置方式:
- 所有地块都不放置房子。
- 一所房子放在街道的某一侧。
- 一所房子放在街道的另一侧。
- 放置两所房子,街道两侧各放置一所。
示例 2:
输入:n = 2
输出:9
解释:如上图所示,共有 9 种可能的放置方式。
提示:
1 <= n <= 104
动态规划
由题意可知,上下两侧互不影响,所以我们只需要算出一边的,然后平方就好了。
用 0 表示该位置没有放置房子,用1表示该位置放置了房子。
dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
dp[i][1] = dp[i - 1][0];
当这个位置不放房子的时候,前一个位置可以有房子,也可以没有房子
当这个位置放置房子的时候,前一个位置只能是没有房子的。
最后的结果就是二者相加的平方
记得要在加的时候,和平方的时候mod一下。
而且为了防止爆int,可以开long long
class Solution {
public:
// 上下两边是不冲突的,可以只算一边,求个平方即可
long long dp[10005][2];
const int mod = 1e9 + 7;
int countHousePlacements(int n) {
dp[1][0] = 1;
dp[1][1] = 1;
for (int i = 2; i <= n; i++) {
dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
dp[i][1] = dp[i - 1][0] % mod;
}
long long t = dp[n][0] + dp[n][1];
t = t * t % mod;
return t;
}
};
找规律
比赛的时候没太看懂题,n = 3的时候枚举错了,导致wa了,wa了两次之后,力扣有提示嘛,可以知道自己在哪个数据wa的,应该输出啥,才知道了 n = 5 时, 结果是169,是13的平方,联想到了斐波那契数列,这道题就是这样推出来的
从n = 3开始
s[n] = s[n - 1] + s[n - 2],且初始化s[1] = 2, s[2] = 3
计算结束之后再输出 平方即可
class Solution {
public:
const int mod = 1e9 + 7;
long long s[10005];
int countHousePlacements(int n) {
long long t = 0;
s[1] = 2;
s[2] = 3;
for (int i = 3; i <= n; i++) {
s[i] = s[i - 1] + s[i - 2];
s[i] %= mod;
}
t = s[n] * s[n] % mod;
int res = t;
return res;
}
};
5229. 拼接数组的最大分数
给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,长度都是 n 。
你可以选择两个整数 left 和 right ,其中 0 <= left <= right < n ,接着 交换 两个子数组 nums1[left…right] 和 nums2[left…right] 。
例如,设 nums1 = [1,2,3,4,5] 和 nums2 = [11,12,13,14,15] ,整数选择 left = 1 和 right = 2,那么 nums1 会变为 [1,12,13,4,5] 而 nums2 会变为 [11,2,3,14,15] 。
你可以选择执行上述操作 一次 或不执行任何操作。
数组的 分数 取 sum(nums1) 和 sum(nums2) 中的最大值,其中 sum(arr) 是数组 arr 中所有元素之和。
返回 可能的最大分数 。
子数组 是数组中连续的一个元素序列。arr[left…right] 表示子数组包含 nums 中下标 left 和 right 之间的元素(含 下标 left 和 right 对应元素)。
示例 1:
输入:nums1 = [60,60,60], nums2 = [10,90,10]
输出:210
解释:选择 left = 1 和 right = 1 ,得到 nums1 = [60,90,60] 和 nums2 = [10,60,10] 。
分数为 max(sum(nums1), sum(nums2)) = max(210, 80) = 210 。
示例 2:
输入:nums1 = [20,40,20,70,30], nums2 = [50,20,50,40,20]
输出:220
解释:选择 left = 3 和 right = 4 ,得到 nums1 = [20,40,20,40,20] 和 nums2 = [50,20,50,70,30] 。
分数为 max(sum(nums1), sum(nums2)) = max(140, 220) = 220 。
示例 3:
输入:nums1 = [7,11,13], nums2 = [1,1,1]
输出:31
解释:选择不交换任何子数组。
分数为 max(sum(nums1), sum(nums2)) = max(31, 3) = 31 。
提示:
n == nums1.length == nums2.length
1 <= n <= 105
1 <= nums1[i], nums2[i] <= 104
最大连续子序和
总体的思路还是最大连续子序和,只不过是对两个数组对应位置数值的差值求最大连续子列和。
最后的最大的和 = a数组和sum + c的最大连续子序和
求的时候可以贪心写,也可以dp推出来。
当前位置的最大连续子序和就是看 前一个位置的最大连续子序和 是否大于0,大于就加上当前值,否则就是当前值
class Solution {
public:
int work(vector<int> &a, vector<int> &b) {
int sum = 0;
for (auto i : a) sum += i;
int dt = 0, f = 0;
for (int i = 0; i < a.size(); i++) {
f = max(0, f) + b[i] - a[i];
dt = max(f, dt);
}
return sum + dt;
}
int maximumsSplicedArray(vector<int>& a, vector<int>& b) {
return max(work(a, b), work(b, a));
}
};