1. 摆动排序II
给你一个整数数组 nums
,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]...
的顺序。
你可以假设所有输入数组都可以得到满足题目要求的结果。
Example
输入:nums = [1,5,1,1,6,4]
输出:[1,6,1,5,1,4]
解释:[1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。
代码
class Solution {
public:
void wiggleSort(vector<int> &nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<int> target(nums.size());
int x = (n + 1) >> 1;
for (int i = 0, j = x - 1, k = n - 1; i < n; i += 2, j--, k--) {
target[i] = nums[j];
if (i + 1 < n) target[i + 1] = nums[k];
}
nums = move(target);
}
};
2. 个位数字为K的整数之和
Given two integers num
and k
, consider a set of positive integers with the following properties:
- The units digit of each integer is
k
. - The sum of the integers is
num
.
Return the minimum possible size of such a set, or -1
if no such set exists.
Note:
- The set can contain multiple instances of the same integer, and the sum of an empty set is considered
0
. - The units digit of a number is the rightmost digit of the number.
Example
输入:num = 58, k = 9
输出:2
代码 [贪心]
class Solution {
public:
int minimumNumbers(int num, int k) {
if (num == 0) return 0;
if ((num & 1) && !(k & 1)) return -1;
int cnt[10]{0}, acc = 0, ans = 0, target = num % 10; // cnt 可用位运算
while (acc <= num) {
acc += k;
if (cnt[acc % 10] == 1) return -1;
++ans;
cnt[acc % 10] = 1;
if (acc % 10 == target) return ans;
}
return -1;
}
};
3. 矩阵的最大非负积
You are given a m x n
matrix grid
. Initially, you are located at the top-left corner (0, 0)
, and in each step, you can only move right or down in the matrix.
Among all possible paths starting from the top-left corner (0, 0)
and ending in the bottom-right corner (m - 1, n - 1)
, find the path with the maximum non-negative product. The product of a path is the product of all integers in the grid cells visited along the path.
Return the maximum non-negative product modulo 10^9 + 7
. If the maximum product is negative, return -1
.
Notice that the modulo is performed after getting the maximum product.
Example
输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 2, target = 4
输出:0.16666666666666666
代码 [动态规划]
class Solution {
private:
long long dot(long long x, long long y) {
if (y == LONG_LONG_MIN) {
return x > 0 ? LONG_LONG_MIN : LONG_LONG_MAX;
}
if (y == LONG_LONG_MAX) {
return x > 0 ? LONG_LONG_MAX : LONG_LONG_MIN;
}
return x * y;
}
public:
int maxProductPath(const vector<vector<int>> &grid) {
int n = grid.size(), m = grid[0].size();
vector<vector<pair<long long, long long>>> dp(n, vector<pair<long long, long long>>(m, {LLONG_MAX, LLONG_MIN}));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (i == 0 && j == 0) {
dp[0][0] = {grid[0][0], grid[0][0]};
continue;
}
if (i > 0) {
long long t1 = dot(grid[i][j], dp[i - 1][j].first), t2 = dot(grid[i][j], dp[i - 1][j].second);
dp[i][j].first = min({dp[i][j].first, t1, t2});
dp[i][j].second = max({dp[i][j].second, t1, t2});
}
if (j > 0) {
long long t1 = dot(grid[i][j], dp[i][j - 1].first), t2 = dot(grid[i][j], dp[i][j - 1].second);
dp[i][j].first = min({dp[i][j].first, t1, t2});
dp[i][j].second = max({dp[i][j].second, t1, t2});
}
}
}
return dp[n - 1][m - 1].second < 0 ? -1 : dp[n - 1][m - 1].second % 1000000007ll;
}
};
4. 课程表
There are a total of numCourses
courses you have to take, labeled from 0
to numCourses - 1
. You are given an array prerequisites
where prerequisites[i] = [ai, bi]
indicates that you must take course bi
first if you want to take course ai
.
- For example, the pair
[0, 1]
, indicates that to take course0
you have to first take course1
.
Return true
if you can finish all courses. Otherwise, return false
.
Example
输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
代码 [DFS]
class Solution {
private:
enum {LEARNING, LEARNED, UNLEARNED};
vector<int> status;
vector<vector<int>> graph;
bool dfs(int i) {
status[i] = LEARNING;
for (int next:graph[i]) {
if (status[next] == LEARNED) continue;
if (status[next] == LEARNING) return false;
if (!dfs(next)) return false;
}
status[i] = LEARNED;
return true;
}
public:
bool canFinish(int n, const vector<vector<int>> &prerequisites) {
status.assign(n, UNLEARNED);
graph.assign(n, {});
for (auto &p:prerequisites) graph[p[0]].push_back(p[1]);
for (int i = 0; i < n; ++i) {
if (status[i] == LEARNED) continue;
if (!dfs(i)) return false;
}
return true;
}
};
4. 路径总和III
给定一个二叉树的根节点 root
,和一个整数 targetSum
,求该二叉树里节点值之和等于 targetSum
的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
Example
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
代码 [暴力DFS]
class Solution {
private:
int result = 0, target;
using ll = long long;
unordered_map<ll, ll> map_union(unordered_map<ll, ll> m1, unordered_map<ll, ll> m2, int add) {
unordered_map<ll, ll> ans;
for (auto[x, y]:m1) ans[x + add] += y;
for (auto[x, y]:m2) ans[x + add] += y;
ans[add]++;
return ans;
}
unordered_map<ll, ll> dfs(TreeNode *root) {
unordered_map<ll, ll> left = root->left ? dfs(root->left) : unordered_map<ll, ll>();
unordered_map<ll, ll> right = root->right ? dfs(root->right) : unordered_map<ll, ll>();
unordered_map<ll, ll> ans = move(map_union(left, right, root->val));
result += ans[target];
return ans;
}
public:
int pathSum(TreeNode *root, int targetSum) {
if (!root) return 0;
target = targetSum;
dfs(root);
return result;
}
};