mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
Update
This commit is contained in:
@ -36,5 +36,5 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
> 更过算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
|
||||
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
|
||||
|
||||
|
63
problems/0093.复原IP地址.md
Normal file
63
problems/0093.复原IP地址.md
Normal file
@ -0,0 +1,63 @@
|
||||
## 题目地址
|
||||
https://leetcode-cn.com/problems/restore-ip-addresses/
|
||||
|
||||
## 思路
|
||||
|
||||
|
||||
## C++代码
|
||||
|
||||
```
|
||||
class Solution {
|
||||
private:
|
||||
vector<string> result;// 记录结果
|
||||
// startIndex: 搜索的起始位置,pointNum:添加逗点的数量
|
||||
void search(string& s, int startIndex, int pointNum) {
|
||||
if (pointNum == 3) { // 逗点数量为3时,分隔结束
|
||||
// 判断第四段子字符串是否合法,如果合法就放进result中
|
||||
if (isValid(s, startIndex, s.size() - 1)) {
|
||||
result.push_back(s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 从起始位置开始构造字段字符串串
|
||||
for (int i = startIndex; i < s.size(); i++) {
|
||||
// 判断 [startIndex,i] 这个区间的子串是否合法
|
||||
if (isValid(s, startIndex, i)) {
|
||||
// 合法,在i的后面插入一个逗点
|
||||
s.insert(s.begin() + i + 1 , '.');
|
||||
// 插入逗点之后下一个子串的起始位置为i+2
|
||||
search(s, i + 2, pointNum + 1);
|
||||
s.erase(s.begin() + i + 1); // 回溯时删掉逗点
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
// 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法
|
||||
bool isValid(const string& s, int start, int end) {
|
||||
if (start > end) {
|
||||
return false;
|
||||
}
|
||||
if (s[start] == '0' && start != end) {// 0开头的数字不合法
|
||||
return false;
|
||||
}
|
||||
int num = 0;
|
||||
for (int i = start; i <= end; i++) {
|
||||
if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法
|
||||
return false;
|
||||
}
|
||||
num = num * 10 + (s[i] - '0');
|
||||
if (num > 255) { // 如果大于255了不合法
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
vector<string> restoreIpAddresses(string s) {
|
||||
result.clear();
|
||||
search(s, 0, 0);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
|
49
problems/0131.分割回文串.md
Normal file
49
problems/0131.分割回文串.md
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
## 题目地址
|
||||
https://leetcode-cn.com/problems/palindrome-partitioning/
|
||||
|
||||
## 思路
|
||||
|
||||
|
||||
## C++代码
|
||||
```
|
||||
class Solution {
|
||||
private:
|
||||
vector<vector<string>> result;
|
||||
|
||||
// startIndex: 搜索的起始位置,vec: 放已经回文的子串
|
||||
void search(const string& s, int startIndex, vector<string>& vec) {
|
||||
// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
|
||||
if (startIndex >= s.size()) {
|
||||
result.push_back(vec);
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < s.size(); i++) {
|
||||
if (isPalindrome(s, startIndex, i)) { // 是回文子串
|
||||
// 获取[startIndex,i]在s中的子串
|
||||
string str = s.substr(startIndex, i - startIndex + 1);
|
||||
vec.push_back(str);
|
||||
} else { // 如果不是则直接跳过
|
||||
continue;
|
||||
}
|
||||
search(s, i + 1, vec); // 寻找i+1为起始位置的子串
|
||||
vec.pop_back(); // 回溯过程,弹出本次已经填在的子串
|
||||
}
|
||||
}
|
||||
bool isPalindrome(const string& s, int start, int end) {
|
||||
for (int i = start, j = end; i < j; i++, j--) {
|
||||
if (s[i] != s[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
vector<vector<string>> partition(string s) {
|
||||
result.clear();
|
||||
vector<string> vec;
|
||||
search(s, 0 , vec);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
@ -2,21 +2,35 @@
|
||||
## 题目地址
|
||||
https://leetcode-cn.com/problems/intersection-of-two-arrays/
|
||||
|
||||
## 思路
|
||||
> 如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!
|
||||
|
||||
这道题目,主要要学会使用一种哈希数据结构,unordered_set,这个数据结构可以解决很多类似的问题。
|
||||
# 第349题. 两个数组的交集
|
||||
|
||||
题意:给定两个数组,编写一个函数来计算它们的交集。
|
||||
|
||||

|
||||
|
||||
**说明:**
|
||||
输出结果中的每个元素一定是唯一的。
|
||||
我们可以不考虑输出结果的顺序。
|
||||
|
||||
# 思路
|
||||
|
||||
这道题目,主要要学会使用一种哈希数据结构:unordered_set,这个数据结构可以解决很多类似的问题。
|
||||
|
||||
注意题目特意说明:**输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序**
|
||||
|
||||
这道题用暴力的解法时间复杂度是O(n^2),这种解法面试官一定不会满意,那看看使用哈希法进一步优化。
|
||||
这道题用暴力的解法时间复杂度是O(n^2),那来看看使用哈希法进一步优化。
|
||||
|
||||
那么可以发现,貌似用数组做哈希表可以解决这道题目,把nums1的元素,映射到哈希数组的下表上,然后在遍历nums2的时候,判断是否出现过就可以了。
|
||||
可以发现,貌似用数组做哈希表可以解决这道题目,把nums1的元素,映射到哈希数组的下表上,然后在遍历nums2的时候,判断是否出现过就可以了。
|
||||
|
||||
但是要注意,使用数据来做哈希的题目,都限制了数值的大小,例如只有小写字母,或者数值大小在[0- 10000] 之内等等。 而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
|
||||
但是要注意,**使用数据来做哈希的题目,都限制了数值的大小,例如[哈希表:可以拿数组当哈希表来用,但哈希值不要太大](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)题目中只有小写字母,或者数值大小在[0- 10000] 之内等等。**
|
||||
|
||||
例如说:如果我的输入样例是这样的, 难道要定义一个2亿大小的数组来做哈希表么, 不同的语言对数组定义的大小都是有限制的, 即使有的语言可以定义这么大的数组,那也是对内存空间造成了非常大的浪费。
|
||||
而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
|
||||
|
||||
此时就要使用另一种结构体了,set ,关于set,C++ 给提供了如下三种可用的数据结构
|
||||
**而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。**
|
||||
|
||||
此时就要使用另一种结构体了,set ,关于set,C++ 给提供了如下三种可用的数据结构:
|
||||
|
||||
* std::set
|
||||
* std::multiset
|
||||
@ -25,9 +39,10 @@ https://leetcode-cn.com/problems/intersection-of-two-arrays/
|
||||
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
|
||||
|
||||
思路如图所示:
|
||||
|
||||

|
||||
|
||||
## 代码
|
||||
# C++代码
|
||||
```
|
||||
class Solution {
|
||||
public:
|
||||
|
@ -3,7 +3,9 @@ https://leetcode-cn.com/problems/ransom-note/
|
||||
|
||||
## 思路
|
||||
|
||||
这道题题意很清晰,就是用判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点1.
|
||||
这道题目和[242.有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)很像,[242.有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
||||
|
||||
本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点1.
|
||||
|
||||
* 第一点“为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思” 这里*说明杂志里面的字母不可重复使用。*
|
||||
|
||||
@ -37,13 +39,12 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
这里时间复杂度是比较高的,而且里面还有一个字符串删除也就是erase的操作,也是费时的,当然这段代码也可以过这道题
|
||||
这里时间复杂度是比较高的,而且里面还有一个字符串删除也就是erase的操作,也是费时的,当然这段代码也可以过这道题。
|
||||
|
||||
我们想一想优化解法
|
||||
|
||||
## 字典计数法(哈希策略)
|
||||
|
||||
因为题目所只有小写字母,那我们可以采用空间换区时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数,然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。
|
||||
因为题目所只有小写字母,那可以采用空间换区时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数,然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。
|
||||
代码如下:
|
||||
|
||||
```C++
|
||||
|
Reference in New Issue
Block a user