LeetCode 专栏收录该内容
11 篇文章 0 订阅

# 2021.11.10 495.提莫攻击

## 代码

class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
int sum = 0;
int length = timeSeries.size();
for(int i = 0; i < length; i++) {
if(i == 0){
continue;
} else {
if(timeSeries[i-1] + duration <= timeSeries[i]) {
sum += duration;
} else{
sum += timeSeries[i] - timeSeries[i-1];
}
}
}
sum += duration;
return sum;
}
};

# 2021.11.11 629.k个逆序对数组

不优化会超出时间限制

## 代码

class Solution {
private:
static constexpr int mod = 1000000007;
public:
int kInversePairs(int n, int k) {
vector<vector<int>> f(2,vector<int>(k+1));
f[0][0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 0; j <= k; j++) {
int cur = i & 1;//1或者0，初始时为1
int prev = cur ^ 1;//1或者0，初始时为0
f[cur][j] = (j - 1 >= 0 ? f[cur][j-1]:0) - (j - i >= 0 ? f[prev][j - i] : 0) + f[prev][j];
if (f[cur][j] >= mod) {
f[cur][j] -= mod;
} else if (f[cur][j] < 0) {
f[cur][j] += mod;
}

}
}
return f[n & 1][k];
}
};



# 2021.11.12 375.猜数字

## 代码

class Solution {
public:
int getMoneyAmount(int n) {
vector<vector<int>> f(n+1,vector<int>(n+1));
for(int d = 2; d <= n; d++) {
for(int i = 1; i <= n-d+1; i++) {
int j = i + d - 1;
f[i][j] = INT_MAX;
for(int x = i + 1; x < j; x ++) {
f[i][j] = min(f[i][j],x + max(f[i][x-1],f[x+1][j]));
}
f[i][j] = min(f[i][j],i+f[i+1][j]);
f[i][j] = min(f[i][j],j+f[i][j-1]);
}
}
return f[1][n];
}
};



另一种写法，因为既要保证f[i][k-1]和f[k+1][j]都已知，正序遍历不能保证f[k+1][j]已知，所以可以倒着遍历。i从后往前遍历，那么f[k+1][j]一定已知。

class Solution {
public:
int getMoneyAmount(int n) {
vector<vector<int>> f(n+1,vector<int>(n+1));
for (int i = n - 1; i >= 1; i--) {
for (int j = i + 1; j <= n; j++) {
int minCost = INT_MAX;
for (int k = i; k < j; k++) {
int cost = k + max(f[i][k - 1], f[k + 1][j]);
minCost = min(minCost, cost);
}
f[i][j] = minCost;
}
}
return f[1][n];

}
};


# 2021.11.13 520.检测大写字母

## 思路

无论第一个字母大小写如何，后面的字母必须和第二个字母大小写相同。

## 代码

class Solution {
public:
bool detectCapitalUse(string word) {
// 若第 1 个字母为小写，则需额外判断第 2 个字母是否为小写
if (word.size() >= 2 && islower(word[0]) && isupper(word[1])) {
return false;
}

// 无论第 1 个字母是否大写，其他字母必须与第 2 个字母的大小写相同
for (int i = 2; i < word.size(); ++i) {
if (islower(word[i]) ^ islower(word[1])) {
return false;
}
}
return true;
}
};

# 2021.11.14 677.键值映射

## 代码

class MapSum {
public:
unordered_map<string,int> m;
MapSum() {

}

void insert(string key, int val) {
m[key] = val;
}

int sum(string prefix) {
int sum = 0;
for (unordered_map<string, int>::iterator it = m.begin(); it != m.end(); it++) {
string s = it->first;
if(s.find(prefix,0) == 0){
sum += it->second;
}
}
return sum;
}
};

/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/

# 2021.11.15 319.灯泡开关

## 思路

第i个灯泡，i开关的次数等约数的个数。

# 代码

class Solution {
public:
int bulbSwitch(int n) {
return sqrt(n + 0.5);
}
};


# 2021.11.16 391.完美矩形

## 代码

typedef pair<int, int> Point;

class Solution {
public:
bool isRectangleCover(vector<vector<int>>& rectangles) {
long area = 0;
int minX = rectangles[0][0], minY = rectangles[0][1], maxX = rectangles[0][2], maxY = rectangles[0][3];
map<Point, int> cnt;
for (auto & rect : rectangles) {
int x = rect[0], y = rect[1], a = rect[2], b = rect[3];
area += (long) (a - x) * (b - y);

minX = min(minX, x);
minY = min(minY, y);
maxX = max(maxX, a);
maxY = max(maxY, b);

Point point1({x, y});
Point point2({x, b});
Point point3({a, y});
Point point4({a, b});

cnt[point1] += 1;
cnt[point2] += 1;
cnt[point3] += 1;
cnt[point4] += 1;
}

Point pointMinMin({minX, minY});
Point pointMinMax({minX, maxY});
Point pointMaxMin({maxX, minY});
Point pointMaxMax({maxX, maxY});
//判断面积是否想等，并且判断最外围的四个顶点是否出现。不判断的话这个样例[0,0,1,1],[0,0,1,1],
//[1,1,2,2],[1,1,2,2]过不了
if (area != (long long) (maxX - minX) * (maxY - minY) || !cnt.count(pointMinMin) || !cnt.count(pointMinMax) || !cnt.count(pointMaxMin) || !cnt.count(pointMaxMax)) {
return false;
}
//擦除最外围的四个顶点
cnt.erase(pointMinMin);
cnt.erase(pointMinMax);
cnt.erase(pointMaxMin);
cnt.erase(pointMaxMax);

for (auto & entry : cnt) {
int value = entry.second;
if (value != 2 && value != 4) {
return false;
}
}
return true;
}
};

# 2021.11.16 318.最大单词长度乘积

## 代码

class Solution {
public:
int maxProduct(vector<string>& words) {
int length = words.size();
for (int i = 0; i < length; i++) {
string word = words[i];
int wordLength = word.size();
for (int j = 0; j < wordLength; j++) {
masks[i] |= 1 << (word[j] - 'a');
}
}
int maxProd = 0;
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
if ((masks[i] & masks[j]) == 0) {
maxProd = max(maxProd, int(words[i].size() * words[j].size()));
}
}
}
return maxProd;
}
};

# 2021.11.18 563.二叉树的坡度

## 代码

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode() : val(0), left(nullptr), right(nullptr) {}
*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int sum = 0;
int findTilt(TreeNode* root) {
dfs(root);
return sum;
}
int dfs(TreeNode* root) {//返回以root为根节点的所有节点的元素之和，同时更新sum
if(root == NULL) {
return 0;
}
int left = dfs(root->left);
int right = dfs(root->right);
sum += abs(left - right);
return left + right + root->val;
}
};

# 2021.11.19 397.整数替换

## 思路

①直接递归，但是得注意越界

class Solution {
public:
int integerReplacement(int n) {
if (n == 1) {
return 0;
}
if (n % 2 == 0) {
return 1 + integerReplacement(n / 2);
}
return 2 + min(integerReplacement(n / 2), integerReplacement(n / 2 + 1));
}
};


②记忆化搜索

class Solution {
private:
unordered_map<int, int> memo;

public:
int integerReplacement(int n) {
if (n == 1) {
return 0;
}
if (memo.count(n)) {
return memo[n];
}
if (n % 2 == 0) {
return memo[n] = 1 + integerReplacement(n / 2);
}
return memo[n] = 2 + min(integerReplacement(n / 2), integerReplacement(n / 2 + 1));
}
};


③贪心算法

class Solution {
public:
int integerReplacement(int n) {
int ans = 0;
while (n != 1) {
if (n % 2 == 0) {
++ans;
n /= 2;
}
else if (n % 4 == 1) {
ans += 2;
n /= 2;
}
else {
if (n == 3) {
ans += 2;
n = 1;
}
else {
ans += 2;
n = n / 2 + 1;
}
}
}
return ans;
}
};


# 2021.11.20 594.最长和谐子序列

## 思路

①先把数组排序，然后找i，j使得|nums[i]-nums[j]|<=1，使得j-i最大。

②使用哈希表记录一下每个元素出现的次数，再遍历每个数组元素x时，查找哈希表中x和x+1的出现的次数，加起来调最大的。

class Solution {
public:
int findLHS(vector<int>& nums) {
unordered_map<int, int> cnt;
int res = 0;
for (int num : nums) {
cnt[num]++;
}
for (auto [key, val] : cnt) {
if (cnt.count(key + 1)) {
res = max(res, val + cnt[key + 1]);
}
}
return res;
}
};


• 0
点赞
• 3
评论
• 0
收藏
• 打赏
• 扫一扫，分享海报

11-21 872

11-20 260
11-30 354
11-15 291
11-19 207
11-18 116
11-28 6
11-18 119
©️2022 CSDN 皮肤主题：1024 设计师：我叫白小胖

dream or nightmare

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。