mirror of
https://gitlab.com/game-loader/hugo.git
synced 2025-04-19 21:42:07 +08:00
leetcode update
This commit is contained in:
parent
d741dbff04
commit
3a3911568f
@ -23231,3 +23231,100 @@ private:
|
||||
};
|
||||
```
|
||||
|
||||
## day344 2025-02-17
|
||||
### 1079. Letter Tile Possibilities
|
||||
You have n tiles, where each tile has one letter tiles[i] printed on it.
|
||||
|
||||
Return the number of possible non-empty sequences of letters you can make using the letters printed on those tiles.
|
||||
|
||||

|
||||
|
||||
### 题解
|
||||
本题的目标即为找到这些字母构成的全部可能组合的个数,因此是经典的可以利用回溯法的场景,但要注意对每个位置遍历可行的字母时对同一个字母仅需遍历一遍,即使该字母有多个,因为只要放在该位置的是同一个字母得到的就会是同一个组合,其对后续继续构建字符串没有影响,考虑ABABA这样的字符串,三个字母A彼此无论怎样交换位置,得到的都还是同一个字符串。
|
||||
则在算法过程中,先统计给定字符串中各个字母的个数放在哈希表中。每当继续放置下一个位置的字母时,遍历当前剩余的可用非重复字母并依次放置在该位置上,将该字母的个数减一,若字母个数为0则从哈希表中移除,每当遍历过程中放置了一个字母均将结果加1,最终即可统计出全部的字符串个数。
|
||||
|
||||
### 代码
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
int numTilePossibilities(std::string tiles) {
|
||||
unordered_map<char, int> counts;
|
||||
for (char tile : tiles) {
|
||||
counts[tile]++;
|
||||
}
|
||||
|
||||
return backtrack(counts);
|
||||
}
|
||||
|
||||
private:
|
||||
int backtrack(unordered_map<char, int>& counts) {
|
||||
int total_sequences = 0;
|
||||
|
||||
for (auto& [tile, count] : counts) {
|
||||
if (count > 0) {
|
||||
total_sequences++;
|
||||
count--;
|
||||
total_sequences += backtrack(counts);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return total_sequences;
|
||||
}
|
||||
};
|
||||
```
|
||||
## day345 2025-02-18
|
||||
### 2375. Construct Smallest Number From DI String
|
||||
You are given a 0-indexed string pattern of length n consisting of the characters 'I' meaning increasing and 'D' meaning decreasing.
|
||||
|
||||
A 0-indexed string num of length n + 1 is created using the following conditions:
|
||||
|
||||
num consists of the digits '1' to '9', where each digit is used at most once.
|
||||
If pattern\[i] == 'I', then num\[i] < num\[i + 1].
|
||||
If pattern\[i] == 'D', then num\[i] > num\[i + 1].
|
||||
Return the lexicographically smallest possible string num that meets the conditions.
|
||||
|
||||

|
||||
|
||||
### 题解
|
||||
本题考虑数组遍历时只能向一个方向遍历,如果从前向后遍历则无法预知后面要给几个D预留出足够大小的数字,即无法拿到后面的关键信息,因此需要遍历两次来获取完整的信息,第一次从后向前遍历,记录连续出现的D的个数,当遇到I时将D的个数赋值给对应位置并将记录的个数清零,这样相当于通知当在这个位置增加数字大小时要提前预留出后面的D个数的大小空间。
|
||||
|
||||
再正向遍历数组,同样也要统计从前一个I到下一个I之间的D的个数m(考虑123546这样的字符串,对于4来说增加的时候不能仅仅加1,还要加上前方减掉的数字大小,因为减掉的这一区间的所有数字已经被使用了,因此我们要恢复到未减数字之前的值并基于此继续向上增加),遇到I时将当前数字加1再增加记录的预留D的个数和m得到下一个值并将m清零。遇到D则将当前数字减一,最终可得满足条件的字符串。因为每次放置数字时都放置了当前位置可能的最小数字,因此这样得到的字符串是字典序最小的
|
||||
|
||||
### 代码
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
string smallestNumber(string pattern) {
|
||||
int len = pattern.size();
|
||||
vector<int> reverse(len,0);
|
||||
int dsum = 0;
|
||||
for(int i=len-1;i>=0;i--){
|
||||
if(pattern[i] == 'D'){
|
||||
dsum++;
|
||||
}else{
|
||||
if(dsum > 0){
|
||||
reverse[i] = dsum;
|
||||
dsum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
char current = '1'+dsum;
|
||||
string result;
|
||||
result += current;
|
||||
int addD = 0;
|
||||
for(int i=0;i<len;i++){
|
||||
if(pattern[i] == 'I'){
|
||||
current = current + 1 + reverse[i] + addD;
|
||||
addD = 0;
|
||||
result += current;
|
||||
}else{
|
||||
addD++;
|
||||
current -= 1;
|
||||
result += current;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user