Leetcode 每日一题 (3.3-3.7)

2021/3/3 338.比特位计数(dp)比特位计数

时间复杂度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. 俄罗斯套娃信封问题(最长递增子序列)

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;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值