力扣刷题02(三数之和+最大子序和+二叉树最近公共祖先)

本文探讨了如何高效解决经典算法问题,如三数之和、最大子序和及买卖股票的最佳时机。通过排序和双指针技术降低时间复杂度,同时介绍了二叉树的最近公共祖先问题的解决方案。动态规划和递归在这些题目中起到了关键作用。
摘要由CSDN通过智能技术生成

三数之和

 经典的求三数之和的题目,两数之和的升级版,该题如果用暴力的话会达到O(nnn)的时间复杂度,为了减少时间复杂度,我们可以用排序加双指针的方法, 先将数组排序一遍,从第一个数开始设为待定的第一个元素再设置两个双指针,l和r,l从第一个元素后面一 位开始遍历,r从最后一位开始,若大于负待定元素,则r向右移,反之则l向左移,知道两指针相遇,若相等 则加入答案数组中。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>>ans;
        if(nums.size()<3){
            return ans;
        }
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++){
            if(i>0&&nums[i]==nums[i-1]) continue;
            int p=nums[i];
            for(int l=i+1,r=nums.size()-1;l<nums.size();l++){
                if(l>i+1&&nums[l]==nums[l-1]) continue;
            
                while(l<r&&nums[l]+nums[r]+p>0){
                    r--;
                }
                if(l==r) break;
                 if(nums[l]+nums[r]+p==0){
                    ans.push_back({nums[l],nums[r],p});
                }
            }
        }
        return ans;
    }
};

最大子序和

 用动态规划写的

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int Max=nums[0];//Max初始值为第一个元素
        int sum=nums[0];//sum值为更新与Max比较的值
        for(int i=1;i<nums.size();i++){
            if(i>0&&sum<0){//如果sum<0去掉之前的值,替换sum为当前值
                sum=nums[i];
                Max=max(Max,sum);
            }
            else if(i>0){//如果sum值>0与当前值相加,并且与Max值比较
                sum+=nums[i];
                Max=max(Max,sum);
            }
            cout<<sum<<endl;
        }
        return Max;
    }
};

买卖股票的最佳时机

改题虽然标的是简单标签,但还是看了题解才会做的T-T,一次遍历即可得出答案。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int Min=1e9;//为股票最低价
        int Max=0;//注意这里不是股票最高价,是目前得到的最高利润
        for(int i=0;i<prices.size();i++){//一次遍历交换数值
           Min=min(Min,prices[i]);
           Max=max(Max,prices[i]-Min);
        }
        return Max;
    }
};


二叉树的最近公共祖先

class Solution {
public:
    TreeNode* ans;
    bool dfs(TreeNode* root,TreeNode* p,TreeNode* q){
        if(root==NULL){
            return false;//如果一直搜索到空节点,则说明没有出现p,q两个节点,返回false
        }
        bool t1=dfs(root->left,p,q);//搜索左子树
        bool t2=dfs(root->right,p,q);//搜索右子树
        if ((t1 && t2) || ((root->val == p->val || root->val == q->val) && (t1 || t2))) {
           //t1和t2都为真或者当前节点为p或q节点且t1或t2有一个为真则使答案为当前节点          
           ans = root;
        }
        return t1||t2||root->val==p->val||root->val==q->val;//当前遍历到p或q节点时,返回true
    } 
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==NULL){
            return ans;
        }//特判root根为空的情况
        dfs(root,p,q);//搜索
        return ans;                                 
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值