leetcode update

This commit is contained in:
gameloader 2025-02-12 12:23:46 +08:00
parent e93cb2c0e6
commit 9c3ddf2e40

View File

@ -22492,3 +22492,492 @@ public:
}
};
```
## day328 2025-01-31
### 827. Making A Large Island
You are given an n x n binary matrix grid. You are allowed to change at most one 0 to be 1.
Return the size of the largest island in grid after applying this operation.
An island is a 4-directionally connected group of 1s.
![0131dAQAVZmcZDI3](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0131dAQAVZmcZDI3.png)
### 题解
本题先从头遍历数组遇到陆地则使用bfs或者dfs遍历整个连通区域。构建一个数组对每个连通区域中的所有陆地都用同一个大于0的数字表示数组中的下标代表该连通区域使用的数字数组的值表示该连通区域的陆地个数如将第一个遇到的连通区域所有陆地都赋值为2第二个则全部赋值为3第三个全部赋值为4。再从头遍历数组对于所有为0的位置查看其四个方向的位置的值若大于0则说明是一个区域获得四个方向全部大于0的值对应编号区域的陆地数量(注意去重)将数量加和再加1即得该处将0变为陆地后能得到的更大连通区域中包含陆地的个数将该值与记录的最大值比较并更新最大值。
### 代码
```cpp
class Solution {
private:
vector<pair<int, int>> dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector<vector<int>>& grid, int x, int y, int mark, int& size) {
int n = grid.size();
grid[x][y] = mark;
size++;
for (const auto& dir : dirs) {
int nx = x + dir.first;
int ny = y + dir.second;
if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == 1) {
dfs(grid, nx, ny, mark, size);
}
}
}
public:
int largestIsland(vector<vector<int>>& grid) {
int n = grid.size();
vector<int> area(n * n + 2, 0);
int mark = 2;
// 第一次遍历:标记不同的岛屿
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
int size = 0;
dfs(grid, i, j, mark, size);
area[mark] = size;
mark++;
}
}
}
if (mark == 2) return 1;
if (mark == 3 && area[2] == n * n) return n * n;
int maxArea = 0;
// 第二次遍历尝试将0变成1
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) {
// 使用数组记录相邻的岛屿标记
int neighbors[4] = {0}; // 最多4个相邻岛屿
int idx = 0;
for (const auto& dir : dirs) {
int nx = i + dir.first;
int ny = j + dir.second;
if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] > 1) {
// 检查是否已经记录过这个岛屿标记
bool found = false;
for (int k = 0; k < idx; k++) {
if (neighbors[k] == grid[nx][ny]) {
found = true;
break;
}
}
if (!found) {
neighbors[idx++] = grid[nx][ny];
}
}
}
// 计算将当前0变成1后的面积
int currentArea = 1;
for (int k = 0; k < idx; k++) {
currentArea += area[neighbors[k]];
}
maxArea = max(maxArea, currentArea);
}
}
}
return maxArea == 0 ? area[2] : maxArea;
}
};
```
## day329 2025-02-01
### 3151. Special Array I
An array is considered special if every pair of its adjacent elements contains two numbers with different parity.
You are given an array of integers nums. Return true if nums is a special array, otherwise, return false.
![0201OvrRgHuBWjIP](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0201OvrRgHuBWjIP.png)
### 题解
本题是一道简单题只需记录前一个数字的奇偶性将当前数字的奇偶性与前一个数字比较如果不同则将奇偶性替换为当前数字的奇偶性。简单说即为使用长度为2的滑动窗口保证窗口内的两个数字奇偶性不同即可否则返回false。
### 代码
```cpp
class Solution {
public:
bool isArraySpecial(vector<int>& nums) {
for(int i=0;i<nums.size()-1;i++){
if(nums[i]%2==nums[i+1]%2){
return false;
}
}
return true;
}
};
```
## day330 2025-02-02
### 1752. Check if Array Is Sorted and rotated
Given an array nums, return true if the array was originally sorted in non-decreasing order, then rotated some number of positions (including zero). Otherwise, return false.
There may be duplicates in the original array.
Note: An array A rotated by x positions results in an array B of the same length such that A[i] == B[(i+x) % A.length], where % is the modulo operation.
![02020Zndtv1DX70l](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/02020Zndtv1DX70l.png)
### 题解
本题是一道简单题数组中的数字只会被旋转一次因此符合要求的数组最多只会有两个连续的非递减序列且第二个序列的最大值小于等于第一个序列的最小值。则使用一个变量指示当前是第几个序列如果当前值大于等于上一个值则序列号不变否则将序列号加一注意此处说的当前值和上一个值包括循环的数组比较即数组最后的值和数组的第一个值。最后若序列号小于等于2则满足条件否则不满足条件。
### 代码
```cpp
class Solution {
public:
bool check(vector<int>& nums) {
int count = 1;
int n = nums.size();
for(int i=0;i<n;i++){
if(nums[i]>nums[(i+1)%n]){
count++;
}
}
return count<=2;
}
};
```
## day331 2025-02-03
### 3105. Longest Strictly Increasing or Strictly Decreasing Subarray
You are given an array of integers nums. Return the length of the longest subarray of nums which is either strictly increasing or strictly decreasing.
![0203WWDm8F4e3G72](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0203WWDm8F4e3G72.png)
### 题解
本题是一道简单题用一个数字记录当前递增或递减子数组的长度和当前是递增还是递减当递增性或者递减性被打破时将该数字与记录的最大值比较并尝试更新最大值再将数字重置为2被打破说明有两个数字的递增递减性发生变化若遇到下一个数字与前一个数字相同则将数字重置为1并尝试更新最大值直到数组末尾再次更新最大值避免漏掉到数组末尾的最后一段子数组。
### 代码
```cpp
class Solution {
public:
int longestMonotonicSubarray(vector<int>& nums) {
int result = 0;
int current = 1;
bool up = true;
for(int i=0;i<nums.size()-1;i++){
if(nums[i]>nums[i+1]){
if(up){
up = false;
result = max(result, current);
current = 2;
}else{
current++;
}
}else if(nums[i]<nums[i+1]){
if(up){
current++;
}else{
up = true;
result = max(result, current);
current = 2;
}
}else{
result = max(result, current);
current = 1;
}
}
result = max(result, current);
return result;
}
};
```
## day332 2025-02-04
### 1800. Maximum Ascending Subarray Sum
Given an array of positive integers nums, return the maximum possible sum of an ascending subarray in nums.
A subarray is defined as a contiguous sequence of numbers in an array.
A subarray \[numsl, numsl+1, ..., numsr-1, numsr\] is ascending if for all i where l <= i < r, numsi < numsi+1. Note that a subarray of size 1 is ascending.
![0204qdE5w3yYGGHg](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0204qdE5w3yYGGHg.png)
### 题解
本题是一道简单题,只需要考虑递增子数组,则如果出现了前后两个数字递减或者相同的情况就重置数组的起始位置和数组和,直到再次遇到递增的情况,将每个递增子数组的和(注意单个数字也算一种递增子数组)与保存的最大值比较并更新最大值。
### 代码
```cpp
class Solution {
public:
int maxAscendingSum(vector<int>& nums) {
int tempsum = nums[0];
int result = nums[0];
for(int i=1;i<nums.size();i++){
if(nums[i] <= nums[i-1]){
result = max(tempsum,result);
tempsum = nums[i];
}else{
tempsum += nums[i];
}
}
result = max(tempsum,result);
return result;
}
};
```
## day333 2025-02-05
### 1790. Check if One String Swap Can Make Strings Equal
You are given two strings s1 and s2 of equal length. A string swap is an operation where you choose two indices in a string (not necessarily different) and swap the characters at these indices.
Return true if it is possible to make both strings equal by performing at most one string swap on exactly one of the strings. Otherwise, return false.
![0205848PLe2NKb9H](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0205848PLe2NKb9H.png)
### 题解
本题是一道简单题直接逐字符遍历两个字符串并挨个字符比较记录两个字符串中同一位置上出现不同字符的次数并且分别记录出现的不同字符如果遍历完成后不同字符出现了两次并且出现的不同字符字符相同仅位置不同一共只有两个字符则为a\[0\]=b\[1]且a\[1]=b\[0]则返回true。否则返回false。
### 代码
```cpp
class Solution {
public:
bool areAlmostEqual(string s1, string s2) {
int count = 0;
vector<char> s1d;
vector<char> s2d;
for(int i=0;i<s1.size();i++){
if(s1[i]!=s2[i]){
count++;
if(count>2){
return false;
}
s1d.push_back(s1[i]);
s2d.push_back(s2[i]);
}
}
if(count==0){
return true;
}else if(count==1){
return false;
}else{
if(s1d[0]==s2d[1] && s1d[1]==s2d[0]){
return true;
}
}
return false;
}
};
```
## day334 2025-02-06
### 1726. Tuple with Same Product
Given an array nums of distinct positive integers, return the number of tuples (a, b, c, d) such that a * b = c * d where a, b, c, and d are elements of nums, and a != b != c != d.
![02064HGY0QL2amCY](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/02064HGY0QL2amCY.png)
### 题解
本题注意满足条件的两组数字进行任意的位置交换都被认为是不同的元组因此满足条件的两组数字共有8种不同的元组构成方式则本题只要找到所有乘积相同的两组数字将这些数字的组数乘8即得最终的结果。
同时发现题目中说明所有的数字均为不同的正整数则任意两个数字相乘得到一个乘积如果同一个乘积出现了多次说明有不同的两数字组可以得到相同的乘积所有数字均不相同同一个数字不可能和两个不同数字相乘得到相同的乘积则能得到相同的乘积两个数字必定均不相同本题只要求计算出最终的数量而不要求列出具体的组合。则计算出数组中全部的两两相乘的乘积并放入哈希表中统计乘积出现的次数再对出现次数大于等于2的乘积计算从中挑选出2个的组合数将全部组合数加和乘8即得最终结果。
### 代码
```cpp
class Solution {
public:
int tupleSameProduct(vector<int>& nums) {
unordered_map<int,int> count;
for(int i=0;i<nums.size();i++){
for(int j=i+1;j<nums.size();j++){
count[nums[i]*nums[j]] = count[nums[i]*nums[j]]+1;
}
}
int result = 0;
for(const pair<int,int>& c : count){
if(c.second >= 2){
result += c.second*(c.second-1)/2;
}
}
return result*8;
}
};
```
## day335 2025-02-07
### 3160. Find the Number of Distinct Colors Among the Balls
You are given an integer limit and a 2D array queries of size n x 2.
There are limit + 1 balls with distinct labels in the range [0, limit]. Initially, all balls are uncolored. For every query in queries that is of the form [x, y], you mark ball x with the color y. After each query, you need to find the number of distinct colors among the balls.
Return an array result of length n, where result[i] denotes the number of distinct colors after ith query.
Note that when answering a query, lack of a color will not be considered as a color.
![0207zFAL62pr2DML](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0207zFAL62pr2DML.png)
### 题解
本题要统计在每次染色后所有现存的球上的不同颜色有多少种。则需要记录三个数据一个是当前所有球上共有多少种不同的颜色另一个则是当前存在的各种颜色对应的存在的球的个数以及不同编号的球上当前对应的颜色编号初始默认所有球上的颜色编号均为0表示没有颜色可以用哈希表来记录每种颜色对应的球的个数和不同球对应的颜色对每个查询给对应的球涂色如果该球以前存在一个颜色则查询哈希表并将该颜色对应的球的个数减一如果归零则将颜色种类减一并将新的颜色对应的球的个数加一如果之前新的新色对应的个数为0则将颜色种类加一将此时的颜色数作为该查询对应的结果插入数组末尾最终返回结果数组。
### 代码
```cpp
class Solution {
public:
vector<int> queryResults(int limit, vector<vector<int>>& queries) {
unordered_map<int,int> balls;
int count = 0;
unordered_map<int,int> colors;
vector<int> result;
for(const auto& query : queries){
if(colors[balls[query[0]]]>0){
if(colors[balls[query[0]]]==1){
count--;
}
colors[balls[query[0]]] = colors[balls[query[0]]]-1;
}
if(colors[query[1]]==0){
count++;
}
colors[query[1]] = colors[query[1]]+1;
balls[query[0]] = query[1];
result.push_back(count);
}
return result;
}
};
```
## day336 2025-02-09
### 2364. Count Number of Bad Pairs
You are given a 0-indexed integer array nums. A pair of indices (i, j) is a bad pair if i < j and j - i != nums[j] - nums[i].
Return the total number of bad pairs in nums.
![0209mlm4TM4DbxKO](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0209mlm4TM4DbxKO.png)
### 题解
本题是一道很有意思的题目首先可以想到与其找j-i != nums\[j\]-nums\[i\]的情况不如找j-i == nums\[j\]-nums\[i\]的情况。因为后者大概是少数而如果保持原来的等式形式等式两边都同时涉及两个无关的变量此时要计算出任意一边都必须同时知道两方的数据而对于全部的数据要全部计算出来只能通过暴力计算的形式全部算出但如果简单的变换一下等式变为j-nums\[j\]==i-nums\[i\]可以发现只是将以前的等式两边做了移项等式仍然成立但此时等式两边都变为了仅和同一个下标相关在算法实现中就产生了非常大的影响因为此时我们只需遍历一次数组将全部i-nums\[i\]的值计算出来统计不同差值各自的个数对于个数大于1的差值通过不断计算求和假设个数为n则满足等式条件的两两下标的组合个数为n-1+n-2+n-3...+1即n*(n-1)/2)最终即得得出全部满足j-nums\[j\]==i-nums\[i\]条件的下标组合的个数。再用该数组能得到的两两组合的总数减去满足等式条件的组合个数即得最终个数。
### 代码
```cpp
class Solution {
public:
long long countBadPairs(std::vector<int>& nums) {
std::unordered_map<int, int> count;
for (int i = 0; i < nums.size(); ++i) {
count[i - nums[i]]++;
}
long long total_pairs = (long long)nums.size() * (nums.size() - 1) / 2;
long long good_pairs = 0;
for (auto const& [diff, freq] : count) {
if (freq > 1) {
good_pairs += (long long)freq * (freq - 1) / 2;
}
}
return total_pairs - good_pairs;
}
};
```
### 总结
本题要注意对于一些描述比较抽象的问题要将题目中的一些条件和意义对应到计算机的算法当中如i有着数组下标这一真实的数据结构含义因此通过变换就可以优化在算法中的计算效率这是由数组本身的特性决定的。即只能一个一个的访问因此要在一次访问中得到尽可能最有用的信息以避免后续重复访问如果数组计算是可以并行进行的如能同时进行下标0和后面全部数组下标的差值及下标对应的数组值的差值的计算则就没必要进行这样的变换处理因为能并行的情况下也只需要n次计算就能得出最终的结果。
## day337 2025-02-10
### 3174. Clear Digits
You are given a string s.
Your task is to remove all digits by doing this operation repeatedly:
Delete the first digit and the closest non-digit character to its left.
Return the resulting string after removing all digits.
![0210qmCG93V9KQ1L](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0210qmCG93V9KQ1L.png)
### 题解
本题每次在移除数字的时候也会移除离数字最近的左侧的非数字字符则每次碰到数字时需要移除连续的数字和紧挨着数字左侧的连续的相同个数的非数字字符如果按照正常的从左向右访问数组则无法预知后面连续的数字的个数则无法确定前面要删除的非数字个数但如果从右向左访问数组当遇到非数字字符时就一定可以知道右侧出现了多少个数字字符。则可以将本题看成一个栈问题遇到数字字符入栈遇到非数字字符就删掉字符并将一个数字出栈如果栈高度为0则保留该非数字字符后续被保留的字符继续在之前保留字符构成的字符串的前方拼接。由于具体的数字对本题无影响因此只需要一个变量记录栈的高度遇到非数字字符删掉字符并减少栈的高度即可。
### 代码
```cpp
class Solution {
public:
string clearDigits(string s) {
string result = "";
int stack_height = 0;
for (int i = s.length() - 1; i >= 0; --i) {
if (isdigit(s[i])) {
stack_height++;
} else {
if (stack_height > 0) {
stack_height--;
} else {
result = s[i] + result;
}
}
}
return result;
}
};
```
## day338 2025-02-11
### 1910. Remove All Occurrences of a Substring
Given two strings s and part, perform the following operation on s until all occurrences of the substring part are removed:
Find the leftmost occurrence of the substring part and remove it from s.
Return s after removing all occurrences of part.
A substring is a contiguous sequence of characters in a string.
![021130kBhBDdvAVa](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/021130kBhBDdvAVa.png)
### 题解
本题注意在删掉一个出现的子字符串后在该子字符串前后的字符可能会组成一个新的满足题意的子字符串有点像消消乐在消掉一个连续图案后前后的图案可能又可以组成连续图案再次消掉达成连击。则可以利用c++的字符串处理函数直接找到匹配part字符串的起始位置从字符串中删掉该位置处的part字符串再次寻找匹配part字符串的位置如此反复直到找不到part的位置。因此s的长度并不长因此该方法的速度也很快。
### 代码
```cpp
class Solution {
public:
string removeOccurrences(string s, string part) {
while (s.find(part) != string::npos) {
s.erase(s.find(part), part.size());
}
return s;
}
};
```
## day339 2025-02-12
### 2342. Max Sum of a Pair With Equal Sum of Digits
You are given a 0-indexed array nums consisting of positive integers. You can choose two indices i and j, such that i != j, and the sum of digits of the number nums\[i] is equal to that of nums\[j].
Return the maximum value of nums\[i] + nums\[j] that you can obtain over all possible indices i and j that satisfy the conditions.
![0212XJH7vnhQnfKu](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0212XJH7vnhQnfKu.png)
### 题解
本题可以用哈希表保存不同数字的数位和对应的最大的两个数字,在遇到新的有相同数位和的数字时将其和这两个数字比较,如果比最大值大,则更新最大值,将最大值放在次大值处,如果仅比次大值大,则仅更新次大值,计算这两个新的最大值的和并与保存的和比较。
### 代码
```cpp
class Solution {
public:
int maximumSum(vector<int>& nums) {
unordered_map<int,pair<int,int>> sums;
int sum = 0;
int maxsum = -1;
for(const auto& num : nums){
sum = sumofnum(num);
if(num > sums[sum].first){
sums[sum].second = sums[sum].first;
sums[sum].first = num;
if(sums[sum].second > 0){
maxsum = max(maxsum,sums[sum].first+sums[sum].second);
}
}else if(num > sums[sum].second){
sums[sum].second = num;
maxsum = max(maxsum,sums[sum].first+sums[sum].second);
}
}
return maxsum;
}
int sumofnum(int num){
int sum = 0;
while(num != 0){
sum += num % 10;
num = num / 10;
}
return sum;
}
};
```