2021/3/3 338.比特位计数(dp)![比特位计数](https://i-blog.csdnimg.cn/blog_migrate/fd4d85d87371b00f1468fe207e4837b1.png)
时间复杂度o(n)的做法:
1、当num是2的次幂的时,num二进制中的1的数目就为1,判断用(num & (num-1)) == 0(注意括号),这样的数标记为high;num不是2的次幂时,设前一个high为x,二进制中1的数目就为count(num-x)+1;
class Solution {
public:
vector<int> countBits(int num) {
vector<int> count(num + 1);
int high = 0;
count[0] = 0;
for(int i = 1; i <= num; i++){
if((i & (i - 1)) == 0){
high = i;
}
count[i] = count[i - high] + 1;
}
return count;
}
};
2、另一种思路是,对于num,将其二进制表示右移一位,等价于将其二进制表示的最低位去掉,得到的数是num/2向下取整,所以当num是奇数时,count[num] = count[num/2] + 1,当num是偶数时,count[num] = count[num/2]。
2021/3/4 354. 俄罗斯套娃信封问题(最长递增子序列)
解法不难想,先是按照第一维递增排序,然后计算排序后的第二维的最长递增子序列即可。
注意:时间复杂度,排序使用快排(sort),冒泡排序tle;统计第二维的最长递增子序列(LIS)时,要考虑到第一维大小相同的情况,当第envelopes[i][1] > envelopes[j][1] 时,需要保证 envelopes[i][0] > envelopes[j][0]。
class Solution {
public:
int maxEnvelopes(vector<vector<int>>& envelopes) {
int size = envelopes.size();
if(size == 0) return 0;
sort(envelopes.begin(), envelopes.end());
vector<int> dp(size, 1);
for(int i = 1; i < size; i++){
for(int j = 0; j < i; j++){
if(envelopes[j][0] < envelopes[i][0] && envelopes[j][1] < envelopes[i][1]){
dp[i] = max(dp[i], dp[j] + 1);
}
}
} //LIS的求法
int ans = 0;
for(int i = 0; i < size; i++){
ans = max(ans, dp[i]);
}
return ans;
}
};
2021/3/5 232. 用栈实现队列(栈和队列)
栈是先进后出,队列先进先出,简单模拟即可
class MyQueue {
public:
stack<int> instack, outstack;
void intoout(){
while(!instack.empty()){
outstack.push(instack.top());
instack.pop();
}
}
/** Initialize your data structure here. */
MyQueue() {}
/** Push element x to the back of queue. */
void push(int x) {
instack.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
if(outstack.empty()){
intoout();
}
int x = outstack.top();
outstack.pop();
return x;
}
/** Get the front element.返回队列头部的元素 */
int peek() {
if(outstack.empty()){
intoout();
}
return outstack.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return instack.empty() && outstack.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
2021/3/6 503. 下一个更大元素 II(栈)
利用一个单调栈即可,在栈内存放的是元素的下标,而这些元素是单调不减的;因为是循环数组,所以需要遍历两边,这里我用了两个for循环,官方题解中直接对下标取模,只需要用一次for循环
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> ans(nums.size(), -1);
stack<int> st;
int size = nums.size();
for(int i = 0; i < size; i++){
while(!st.empty() && nums[i] > nums[st.top()]){
ans[st.top()] = nums[i];
st.pop();
}
st.push(i);
}
for(int i = 0; i < size; i++){
while(!st.empty() && nums[i] > nums[st.top()]){
ans[st.top()] = nums[i];
st.pop();
}
}
return ans;
}
};
2021/3/7 131. 分割回文串(回溯)
回溯(再看!!!!!!!!!)
class Solution {
private:
vector<vector<int>> f;
vector<vector<string>> ret;
vector<string> ans;
int n;
public:
void dfs(const string& s, int i){
if(i == n){
ret.push_back(ans);
return;
}
for(int j = i; j < n; j++){
if(f[i][j]){
ans.push_back(s.substr(i, j - i + 1));
dfs(s, j + 1);
ans.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
n = s.size();
f.assign(n, vector<int>(n, true));
for(int i = n - 1; i >= 0; --i){
for(int j = i + 1; j < n; j++){
f[i][j] = (s[i] == s[j]) && f[i + 1][j - 1];
}
}
dfs(s, 0);
return ret;
}
};