50.日常算法
1. 非递减子序列
题目来源
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
示例 1:
输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]
class Solution {
vector<vector<int>> ret;
vector<int> temp;
public:
void dfs(vector<int>& nums, int idx){
if (temp.size() >= 2) ret.push_back(temp);
unordered_set<int> hash;
for (int i = idx; i < nums.size(); ++i){
if ((!temp.empty() && temp.back() > nums[i]) || (hash.find(nums[i]) != hash.end())) continue;
hash.insert(nums[i]);
temp.push_back(nums[i]);
dfs(nums, i + 1);
if (temp.size() > 0) temp.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
dfs(nums, 0);
return ret;
}
};
2. 爬楼梯
题目来源
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
// 注意:这里不能使用递归,递归会超时
class Solution {
public:
int climbStairs(int n) {
int i = 1;
int j = 2;
if (n == 1) return 1;
if (n == 2) return 2;
int ret = 0;
for (int k = 3; k <= n; ++k){
ret = i + j;
i = j;
j = ret;
}
return ret;
}
};