1089. Duplicate Zeros
给定一个整型数组,若遇到0,则将其重复一遍,剩下数字后移一位,在原数组上进行操作
直接新开一个数组,遍历一遍,同时判断是否为0,最后替换原数组即可
class Solution {
public:
void duplicateZeros(vector& arr) {
vector res;
int i = 0;
while (res.size() < arr.size())
{
res.emplace_back(arr[i]);
if (arr[i] == 0) res.emplace_back(0);
i++;
}
while (res.size() > arr.size())
res.pop_back();
arr = res;
}
};
1090. Largest Values From Labels
给定两个数组和两个数字,数组分别为values和labels,每个value都与其下标相同的label相对应,wanted表示需要多少value,limit表示每个label最多可以被使用多少次,返回所能得到最大的value和
自定义了一个结构,保存value与label(也可以单用一个pair来保存)
然后按照value值从大到小排序,遍历一遍,判断是否达到label的上限(用map保存每个label 的使用次数),以及是否达到所需的value数目
struct valLab
{
int value;
int label;
};
class Solution {
public:
int largestValsFromLabels(vector& values, vector& labels, int num_wanted, int use_limit) {
valLab vl;
vector v;
for (int i = 0; i < values.size(); ++i)
{
vl.value = values[i], vl.label = labels[i];
v.emplace_back(vl);
}
sort(v.begin(), v.end(),
[&](const valLab& a, const valLab& b)
{
return a.value > b.value;
});
unordered_map m;
int cnt = 0, res = 0;
for (valLab vl : v)
{
if (cnt >= num_wanted) break;
if (m[vl.label] == use_limit) continue;
res += vl.value;
m[vl.label] ++;
cnt++;
}
return res;
}
};
1091. Shortest Path in Binary Matrix
给定一个只含有0和1的grid,判断从左上角到右下角的最短路径(可走8个方向),若不存在路径,则返回-1
这道题感觉没说清楚,也可能是我阅读理解问题?看第一个案例以为初始值为0,对角线的路径要+2,结果总是报错,后来试了下8个方向都是+1,初始值为1,才通过
很典型的bfs题了,每次保存该点是否被访问过以及是否为终点,一层层往外遍历即可
要注意当初始点或终点是1,即无法到达,直接返回-1
class Solution {
public:
int shortestPathBinaryMatrix(vector>& grid) {
int dx[8] = { 0, 0, 1, 1, 1, -1,-1, -1 };
int dy[8] = { 1, -1,0, 1, -1, 0, 1, -1 };
queue> q;
int r = grid.size(), c = grid[0].size();
if(grid[0][0] == 1 || grid[r - 1][c - 1] == 1) return -1;
if (r + c == 0) return 0;
vector> visited(r, vector(c, 0));
visited[0][0] = 1;
q.emplace(make_pair(0, 0));
int cnt = 1;
while (!q.empty())
{
cnt++;
queue> tmp;
while (!q.empty())
{
pair p = q.front();
q.pop();
for (int i = 0; i < 8; ++i)
{
int x = p.first + dx[i], y = p.second + dy[i];
if (x >= 0 && x < r && y >= 0 && y < c && visited[x][y] == 0 && grid[x][y] == 0)
{
if (x == r - 1 && y == c - 1) return cnt;
visited[x][y] = 1;
tmp.emplace(make_pair(x, y));
}
}
}
q = tmp;
}
return -1;
}
};
1092. Shortest Common Supersequence
给定两个字符串,找出最短序列,使其包含两个字符串
参考1092. 根据LCS(最长公共子序列)的路径逆向构造答案的思路
根据题意,既然要所得序列最短,则须保证原字符串中相同字符合并,因此需要求出两个字符串的最长公共子序列
比如以例题为例,"abac"和"cab"构成的最长公共子序列(LCS)数组为:
00000
00001
01111
01222
因此LCS长为2,此时再逆向推导构造,最后反转即可
class Solution {
public:
string shortestCommonSupersequence(string str1, string str2) {
int m = str1.length(), n = str2.length();
// LCS
vector> dp(m + 1, vector(n + 1, 0));
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (str1[i] == str2[j])
dp[i + 1][j + 1] = dp[i][j] + 1;
else
dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]);
}
}
string res = "";
while (m > 0 || n > 0)
{
if (m == 0)
{
res += str2[--n];
continue;
}
if (n == 0)
{
res += str1[--m];
continue;
}
if (str1[m - 1] == str2[n - 1])
{
res += str1[m - 1];
m--, n--;
continue;
}
if (dp[m][n] == dp[m][n - 1])
res += str2[--n];
else res += str1[--m];
}
reverse(res.begin(), res.end());
return res;
}
};