2022-03-17剑指59-68

面试题59

题解链接

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
        int n=num.size();
        int low=1-size, high=0;//滑窗头,滑窗尾
        deque<int> dq;
        vector<int> res;
        while(high<n){//low和high是移动以后的左右边界,所以dq加进来的是num[high]
            //可能舍弃的是num[low-1]
            if(low>=1 && num[low-1]==dq[0]) dq.pop_front();
            while(!dq.empty() && dq[0] < num[high]) dq.pop_front();//先处理high,也就是右边更新
            while(!dq.empty() && dq[dq.size()-1]<num[high]) dq.pop_back();//双端队列两边都处理一下
            dq.push_back(num[high]);
            
            if(low>=0) res.push_back(dq[0]);
            low++;
            high++;
        }
        return res;
    }
};

面试题60

题解链接
时间O(n^2)
空间O(n^2)

class Solution {
public:
    vector<double> dicesProbability(int n) {
        int dp[n+1][n*6+1];
        memset(dp, 0, sizeof(dp));
        for(int i=1; i<=6; ++i){
            dp[1][i]=1;
        }
        for(int i=2; i<=n; ++i){
            for(int j=i*1; j<=i*6; ++j){//j是i个骰子点数和,i*1 to i*6
                for(int k=1; k<=6; ++k){//k是第i个骰子的点数
                    if(j-k <= 0){
                        break;//跳出当前循环
                    }
                    dp[i][j]+=dp[i-1][j-k];
                }
            }
        }
        int all=pow(6,n);//所有可能结果的数量
        vector<double> ret;
        for(int i=n; i<=6*n; ++i){
            ret.push_back(dp[n][i] * 1.0/all);
        }
        return ret;
    }
};

空间优化

class Solution {
public:
    vector<double> dicesProbability(int n) {
        //空间优化,dp是n个骰子掷出各个点数的出现次数,按i更新整个dp表
        int dp[n*6+1];
        memset(dp, 0, sizeof(dp));
        for(int i=1; i<=6; ++i){
            dp[i]=1;
        }
        for(int i=2; i<=n; ++i){
            for(int j=i*6; j>=i*1; --j){//后往前更新
                dp[j]=0;
                for(int k=1; k<=6; ++k){//k是第i个骰子的点数
                    if(j-k < i-1){//前i-1个骰子的点数是j-k
                        break;//跳出当前循环
                    }
                    dp[j]+=dp[j-k];
                }
            }
        }
        int all=pow(6,n);//所有可能结果的数量
        vector<double> ret;
        for(int i=n; i<=6*n; ++i){
            ret.push_back(dp[i] * 1.0/all);
        }
        return ret;
    }
};

面试题61

思路:set存遇到的非0数,遍历如果有重复,就false,否则,维护一个最大最小,最大-最小<5的话就是true,否则false,注意最大可以初始化为0,但最小不能初始化为0
时间O(n),空间O(n),其实就5个,时间空间可以忽略不计。

class Solution {
public:
    bool isStraight(vector<int>& nums) {
        unordered_set<int> st;
        int maxNum=nums[0],minNum=nums[0];
        for(int i=0; i<nums.size(); ++i){
            if(nums[i]!=0){
                if(minNum==0) minNum=nums[i];
                //minNum等于0的话要换成不等于0的数
                maxNum=max(nums[i],maxNum);
                minNum=min(nums[i],minNum);    
            }
            if(nums[i]!=0 && st.count(nums[i])){
                return false;
            }
            //st.insert(nums[i]);
            if(nums[i]!=0) st.insert(nums[i]);
        }
        return maxNum-minNum<5;
        //return (maxNum-minNum<5);
    }
};

面试题62

题解链接

递归

class Solution {
public:
    int LastRemaining_Solution(int n, int m) {
        if(n==1) return 0;
        return (LastRemaining_Solution(n-1, m)+m)%n;
    }
};

迭代,先写递归,再优化成迭代

class Solution {
public:
    int LastRemaining_Solution(int n, int m) {
        if(n==1) return 0;
        int f=0;
        for(int i=2;i<=n; ++i){
            f=(f+m)%i;//注意这个i,容易写成n
        }
        return f;
    }
};

面试题63

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        // write code here
        if(prices.size()==0) return 0;
        int buyMin=prices[0];
        int ans=0;
        for(int i=0; i<prices.size(); ++i){
            if(prices[i]<buyMin){
                buyMin=prices[i];
            }
            ans=max(ans, prices[i]-buyMin);
        }
        return ans;
    }
};

面试题64

题解链接

class Solution {
public:
    int Sum_Solution(int n) {
        bool x = n > 1 && (n += Sum_Solution(n-1)); // bool x只是为了不报错
        return n;
    }
};

面试题65

题解链接

class Solution {
public:
    int Add(int num1, int num2) {
        while(num2!=0){
            int c=(unsigned int)(num1&num2)<<1;
            //要先unsigned int再左移
            num1^=num2;
            num2=c;
        }
        return num1;
    }
};

面试题66

题解链接


class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
    //迭代就行了
        int n=A.size();
        if(n==0) return {};
        vector<int> B(A.size(),1);
        int tmp=1;
        //下三角
        for(int i=1; i<n; ++i){
            B[i]=B[i-1]*A[i-1];
        }
        //上三角
        for(int i=n-2; i>=0; --i){
            tmp*=A[i+1];
            B[i]*=tmp;
        }
        return B;
    }
};

面试题67

题解链接

class Solution {
public:
    int StrToInt(string s) {
        // write code here
        int border=INT_MAX/10;
        int i=0;
        //空格
        while(i<s.size() && s[i]==' ')
            ++i;
        //符号位
        bool sign=0;
        if(s[i]=='-') sign=1;//注意只要开头一个符号,所以不能while
        if(s[i]=='-' || s[i]=='+') ++i;
        //数字,不是数字的就返回
        int ans=0;
        for(int j=i; j<s.size(); ++j){
            if(!isdigit(s[j]))
                break;
            else if(j==i)
                ans=s[j]-'0';
            else{
                if(ans>border || (ans==border && s[j]>'7'))
                    return sign?INT_MIN:INT_MAX;
                ans=ans*10+(s[j]-'0');
            }
        }
        return sign?ans*-1:ans;
    }
};

面试题68

class Solution {
public:
    int lowestCommonAncestor(TreeNode* root, int p, int q) {
        // write code here
        if(p==root->val || q==root->val) return root->val;
        if((p<root->val && q>root->val)||(p>root->val && q<root->val))
            return root->val;
        //否则在同一侧
        if(p<root->val){//左侧
            return lowestCommonAncestor(root->left, p, q);
        }
        else{
            return lowestCommonAncestor(root->right, p, q);
        }
    }
};

知识

deque,pop_back(),pop_front(),可直接访问,deque[0]这种

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值