leetcode update

This commit is contained in:
gameloader 2024-09-15 18:39:37 +08:00
parent 242a7ef404
commit 50046a4e63

View File

@ -13248,3 +13248,145 @@ func countConsistentStrings(allowed string, words []string) int {
return result return result
} }
``` ```
## day199 2024-09-13
### 1310. XOR Queries of a Subarray
You are given an array arr of positive integers. You are also given the array queries where queries[i] = [lefti, righti].
For each query i compute the XOR of elements from lefti to righti (that is, arr[lefti] XOR arr[lefti + 1] XOR ... XOR arr[righti] ).
Return an array answer where answer[i] is the answer to the ith query.
![0913HP8rsSdDtlxy](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0913HP8rsSdDtlxy.png)
### 题解
本题可使用"前缀和". 考虑到每次计算query都是从query的lefti异或到righti. 之前提到过精准计算某一段的值可以用以该段段尾为结尾的前缀和减去该段段首为结尾的前缀和. 在这里同样如此, 要用到异或的特性, a^b^c的值再与a异或相当于b^c. 则可先计算出arr数组的全部元素的前缀"异或和"(即求到当前下标的子数组的全部异或后的结果). 在计算query时用到段尾下标的前缀"异或和"与到段首下标的前缀"异或和"异或即得中间部分的异或和.
注意求[0,1]的异或和是求0位和1位异或的结果, 是包含0位的, 而求前缀和时相当于从下标"-1"开始计算, 需要在前缀和数组前面补充一个值为0的前缀和表示"-1"的值, 这样求[0,1]的前缀和时就是用1的前缀和减去"-1"的前缀和
### 代码
```go
func xorQueries(arr []int, queries [][]int) []int {
prefix := []int{0}
prexor := 0
for _, num := range arr{
prexor = prexor ^ num
prefix = append(prefix, prexor)
}
result := []int{}
for _,query := range queries{
result = append(result, prefix[query[0]] ^ prefix[query[1]+1])
}
return result
}
```
## day200 2024-09-14
### 2419. Longest Subarray With Maximum Bitwise AND
You are given an integer array nums of size n.
Consider a non-empty subarray from nums that has the maximum possible bitwise AND.
In other words, let k be the maximum value of the bitwise AND of any subarray of nums. Then, only subarrays with a bitwise AND equal to k should be considered.
Return the length of the longest such subarray.
The bitwise AND of an array is the bitwise AND of all the numbers in it.
A subarray is a contiguous sequence of elements within an array.
![0914zXkuivxqDnnG](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0914zXkuivxqDnnG.png)
### 题解
本题也是一道和位运算有关的问题, 乍一看这个问题似乎和昨天的问题有几分相似, 看到题面可能会想到只能计算出所有子数组的按位与, 同时记录当前子数组按位并的最大值, 以及最大值对应子数组的长度. 最终得到结果.
但是位运算一定有些自身的特点可以帮助我们减少需要遍历的子数组的个数, 我们考虑任意两个数进行按位与, 可以发现任意一个数的某一位为0则运算的结果中该位即为0, 则可以肯定, 对于两个不同的数, 进行按位与得到的结果肯定比两个数中较大的那个小(二进制0的个数最少也要和小的数一样多, 如1和3与得到1). 则由此我们只需在遍历数组时记下当前最大值, 并记下当前该最大值连续出现时出现的次数的最大值, 最终即得到结果.
### 代码
```cpp
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int max = 0;
int longest = 1;
int current = 0;
for (auto iter : nums){
if (iter > max){
max = iter;
longest = current = 1;
}else if (iter == max){
current++;
if (current > longest){
longest = current;
}
}else{
current = 0;
}
}
return longest;
}
};
```
## day201 2024-09-15
### 1371. Find the Longest Substring Containing Vowels in Even Counts
Given the string s, return the size of the longest substring containing each vowel an even number of times. That is, 'a', 'e', 'i', 'o', and 'u' must appear an even number of times.
![091589L5p3UZ9skI](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/091589L5p3UZ9skI.png)
### 题解
本题第一步容易想到可以使用"前缀和"记录到每个下标的前缀子字符串中各个元音字母个数的奇偶性. 找最长的包含偶数元音字母的子字符串即寻找两个距离最远的下标, 且以这两个下标结尾的前缀子字符串中各个元音字母个数的奇偶性相同. 此时可以想到可以用数组来保存每个元音字母个数的奇偶性, 这样就需要长度为5的数组, 可以是整型数组也可以是布尔数组(仅有奇或者偶两种状态). 只是在比较任意两个下标对应的前缀子字符串元音奇偶性是否相同时需要遍历这个数组.
有没有更快的方法可以避免遍历数组呢? 可以想到对于奇偶这种二值状态, 仅需要一个二进制位就能表示, 而任意一个整型都包含32个二进制位, 所以用一个整数表示五个元音字母的奇偶状态是完全没问题的. 这里是充分利用每个二进制位能包含的信息. 有一个经典问题, 即1000瓶水里有一瓶是有毒的, 需要多少只老鼠才能试出那瓶有毒的毒药(可怜的鼠鼠)也是相同的思想.
有了这个想法后, 我们可以用一个整数来表示到某个下标的前缀子字符串中元音字母的奇偶性, 只要两个下标处对应的整数相同, 则二者之间的子字符串就满足题目要求. 考虑五个元音字母用二进制表示对应的整数最大为31. 可以直接构造一个长度32的二维数组, 记录每个整数对应的开始下标和当前的最长长度, 如此即可在一遍遍历字符串的同时不断更新该数组, 得到每个整数对应的最长长度, 最后遍历这个二维数组, 找出最长长度中的最长长度即得结果.
### 代码
```cpp
class Solution {
public:
int findTheLongestSubstring(string s) {
int rows = 32;
int cols = 2;
int currentmask = 0;
int index = 0;
vector<vector<int>> array(rows, vector<int>(cols, -1));
int max_length = 0;
for (char character : s) {
switch (character) {
case 'a': currentmask ^= 1; break;
case 'e': currentmask ^= 2; break;
case 'i': currentmask ^= 4; break;
case 'o': currentmask ^= 8; break;
case 'u': currentmask ^= 16; break;
}
if (currentmask != 0) {
if (array[currentmask][0] == -1) {
array[currentmask][0] = index;
} else {
array[currentmask][1] = index - array[currentmask][0];
max_length = max(max_length, array[currentmask][1]);
}
} else {
max_length = max(max_length, index + 1);
}
index++;
}
return max_length;
}
};
```