前言:为了找到一份暑期的实习,争取早日刷够200题!!
题46.全排列(中等)
方法:回溯法;深度优先遍历 (DFS)
题目:
class Solution {
public:
void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){
// 所有数都填完了
if (first == len) {
res.emplace_back(output);
return;
}
for (int i = first; i < len; ++i) {
// 动态维护数组
swap(output[i], output[first]);
// 继续递归填下一个数
backtrack(res, output, first + 1, len);
// 撤销操作
swap(output[i], output[first]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > res;
backtrack(res, nums, 0, (int)nums.size());
return res;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析:
- 时间复杂度: O(n×n!),其中 nn 为序列的长度。
空间复杂度:O(n)O(n),其中 nn 为序列的长度。除答案数组以外,递归函数在递归过程中需要为每一层递归函数分配栈空间,所以这里需要额外的空间且该空间取决于递归的深度,这里可知递归调用深度为 O(n)O(n)
C++知识点:
vector是我们常用的容器,向其中增加元素的常用方法有:emplace_back和push_back两种。
- push_bach():
首先需要调用构造函数构造一个临时对象,然后调用拷贝构造函数将这个临时对象放入容器中,然后释放临时变量。
- emplace_back():
这个元素原地构造,不需要触发拷贝构造和转移构造。
建议使用emplace_back()
题47 全排序Ⅱ
方法:回溯
题目:
class Solution {
vector<int> vis;
public:
void backtrack(vector<int>& nums, vector<vector<int>>& ans, int idx, vector<int>& perm) {
if (idx == nums.size()) {
ans.emplace_back(perm);
return;
}
for (int i = 0; i < (int)nums.size(); ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
perm.emplace_back(nums[i]);
vis[i] = 1;
backtrack(nums, ans, idx + 1, perm);
vis[i] = 0;
perm.pop_back();
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ans;
vector<int> perm;
vis.resize(nums.size());
sort(nums.begin(), nums.end());
backtrack(nums, ans, 0, perm);
return ans;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations-ii/solution/quan-pai-lie-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
实话实说,这道题给爷看吐了,本来以为看懂了,这里多了个条件直接不会了。
这里有个技巧,排序后重新填。有时间再看吧,真的难顶。
题20 有序的括号
方法:栈
题目:
class Solution {
public:
bool isValid(string s) {
stack<char> ans;
for(int i=0;i<s.length();++i)
{
if(ans.size()==0 )
{
if(s[i]==')' || s[i]==']' || s[i]=='}' )
return false;
}
if(s[i]=='(' || s[i]=='[' || s[i]=='{')
{
ans.push(s[i]);
}
if(s[i]==')')
{
if(ans.top()=='(')
{ans.pop();}
else
{return false;}
}
if( s[i]==']' )
{
if(ans.top()=='[')
{ans.pop();}
else
{return false;}
}
if( s[i]=='}')
{
if(ans.top()=='{')
{ans.pop();}
else
{return false;}
}
}
if(ans.size()==0)
{ return true;}
else
{return false;}
}
};
C++:
注意 单引号 和 双引号的区别,一开始使用双引号报错!
单引号是字符型, 双引号是字符串型
举例:
"a"和’a’的区别,前者是字符串,后者是字符。
实际上 ”a" 是 “a\0”,以’\0’结尾。而‘a’单单表示a这个字符。
字符串可以是"abcde"这样的表示多个字符的一个组合,但是’abcde’这样就是错误的!!
剑指Offer 24题 反转链表
- 两种解法:迭代 和 递归!
- 迭代使用双指针,递归需要一步一步推导,多多理解!
题15 三数之和
方法:排序+双指针 关键在去除重复解 (和之前的trick一样 ,先排序 然后和前一个相同跳过)
今天太累了,找时间在自己写一遍!