860.柠檬水找零
题目大意:给出一个买5美元东西支付序列(只有5,10,20元),问是否能成功找零
题解:简单模拟题,20元时优先用10元
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int t, cnt=, cnt2=, cnt3=;
for(int i=; i<bills.size(); i++) {
int t=bills[i];
if (t==) cnt++;
else if (t==) {
cnt2++;
if (!cnt) return false;
else cnt--;
}
else if (t==) {
cnt3++;
if (cnt2&&cnt) {
cnt2--;
cnt--;
continue;
}
if (cnt>=) {
cnt-=;
continue;
}
return false;
}
}
return true;
}
};
863.二叉树中所有距离为 K 的结点
题目大意:给出一个二叉树,问距离给定的点距离为K的结点有哪些
题解:将给定的点变为根建树就好了,深度就是距离了
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> ans;
vector<int> V[];
void Build(TreeNode* cur) {
if (cur->left!=NULL) {
V[cur->val].push_back(cur->left->val);
V[cur->left->val].push_back(cur->val);
Build(cur->left);
}
if (cur->right!=NULL) {
V[cur->val].push_back(cur->right->val);
V[cur->right->val].push_back(cur->val);
Build(cur->right);
}
}
void dfs(int cur, int fa, int d, int K) {
if (d==K) ans.push_back(cur);
for(int i=; i<V[cur].size(); i++) {
int u=V[cur][i];
if (u!=fa) dfs(u, cur, d+, K);
}
}
vector<int> distanceK(TreeNode* root, TreeNode* target, int K) {
if (root==NULL) {
vector<int> tmp;
return tmp;
}
Build(root);
dfs(target->val, -, , K);
return ans;
}
};
861.翻转矩阵后的得分
题目大意:给定一个矩阵,操作定义为一行或一列的1变成0,0变成1,问任意次操作后,数字总和最大为多少
题解:很容易想到一个贪心的做法,先将每一位最高为变成1,再将每一列1的个数尽量多,根据二进制的一些性质可以证明这样是最优的
class Solution {
public:
int a[][];
int matrixScore(vector<vector<int>>& A) {
int n=A.size();
if (!n) return ;
int m=A[].size();
for(int i=; i<n; i++) {
for(int j=; j<m; j++) {
a[i][j]=A[i][j];
}
}
for(int i=; i<n; i++) {
if (a[i][]==) {
for(int j=; j<m; j++) {
a[i][j]=-a[i][j];
}
}
}
for(int j=; j<m; j++) {
int cur=;
for(int i=; i<n; i++) {
cur+=a[i][j];
}
if (cur<n-cur) {
for(int i=; i<n; i++) {
a[i][j]=-a[i][j];
}
}
}
int sum=;
for(int i=; i<n; i++) {
int row=;
for(int j=; j<m; j++) {
row=row*+a[i][j];
}
sum=sum+row;
}
return sum;
}
};
862.和至少为K的最短子数组
题目大意:给出一个可正可负数组,问至少为K的最短子数组的长度
题解:连续和转化为前缀和的差,对于每一个sum[i],要找到一个sum[j]<=sum[i]-k,j要尽量大,很自然我们会想到二分,然而会发现sum[j]并不是单调的,但我们发现当 k < j,sum[k] >= sum[j],这样的k是永远都不会用到,所以用一个单调栈优化一下,这样就可以二分了
#define pb push_back
#define mp make_pair
#define CLR(a) memset(a, 0, sizeof(a))
#define DBG(x) cout<<(#x)<<"="<<x<<endl
#define FOR(i, a, b) for(int i=(a); i<(b); i++)
#define REP(i, a, b) for(int i=(a); i<=(b); i++)
#define DOWN(i, a, b) for(int i=(a); i>=(b); i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const double eps = ;
const int INF = ;
const ll LL_INF = ;
const ll mod = ;
const int N = + ;
class Solution {
public:
int shortestSubarray(vector<int>& A, int K) {
ll sum[];
vector<pll> V;
ll n=A.size();
ll ans=;
sum[]=A[];
for(int i=; i<n; i++) {
sum[i]=sum[i-]+A[i];
}
V.pb(mp(, -));
for(int i=; i<n; i++) {
auto pos=upper_bound(V.begin(), V.end(), mp(sum[i]-K, i+l));
if (pos!=V.begin()) {
pos--;
ans=min(ans, i- (*pos).second );
}
while (V.size()> && sum[i]<=V.back().first) V.pop_back();
V.pb(mp(sum[i], i));
}
if (ans==) return -;
else return ans;
}
};