LeetCode每周刷题总结3.20-3.26

17 篇文章 0 订阅
4 篇文章 0 订阅

上周重感冒导致鸽了。本周继续砥砺前行。
第四周力扣刷题记录总结:

543.二叉树的直径

543.二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

  1
     / \
    2   3
   / \     
  4   5    

解题思路:递归找左右两边最深的,max取左右两边的最大值。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {

    int ans;
    int depth(TreeNode* root) {
    if(root==nullptr)
        return 0;
    int l = depth(root->left);
    int r = depth(root->right);
    ans = max(ans,l+r+1);
    return max(l,r)+1;
    }
    public:
    int  diameterOfBinaryTree(TreeNode* root){
        ans = 1;
        depth(root);
        return ans -1;
    }
};

287. 寻找重复数

287. 寻找重复数
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

解题思路:map记录 遇到重复的

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
    map<int,int> m;
    for(auto x:nums)
    {
        m[x]++;
        if(m[x]>=2)
            return x;
    }
            return -1;
    }
};

102. 二叉树的层序遍历

102. 二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
在这里插入图片描述
解题思路:
采用类似于BFS的思想进行。

  • 首先根元素入队
  • 当队列不为空的时候,求当前队列的长度 si,依次从队列中取 si个元素进行拓展,然后进入下一次迭代。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> v;
            if(!root)
                return v;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty())
        {
            int Size = q.size();
            v.push_back(vector<int>());
            for(int i = 1;i<=Size;i++)
            {
                auto node = q.front();
                q.pop();
                v.back().push_back(node->val);
                if(node->left)
                    q.push(node->left);
                if(node->right)
                    q.push (node->right);
            }
        }
        return v;
    }
};

46. 全排列

46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
在这里插入图片描述
解题思路:DFS,将遍历到的数字压入栈。

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
    dfs(nums);
        return res;
    }
private:
    vector<vector<int>>res;
    vector<int> v;
    void dfs(vector<int>& nums)
    {
        if(v.size()==nums.size())
        {
            res.push_back(v);
            return;
        }
        for(int i =0;i<nums.size();i++)
        {
                if(nums[i]!=99){//仅表示为不可能出现的两位数.
                int temp = nums[i];
                v.push_back(temp);
                nums[i]=99;
                dfs(nums);
                nums[i]=temp;
                v.pop_back();
        }
        }
    }
};

3. 无重复字符的最长子串

3. 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
解题思路:利用set 集合。最大值等于i-l+1。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size()==0)
            return 0;
        set<char> S;
        int Max  = 0;
        int l =0;
        for(int i = 0 ;i<s.size();i++)
        {
            while(S.find(s[i])!=S.end())
            {
                S.erase(s[l]);
                l++;
            }
            Max= max(Max,i-l+1);
            S.insert(s[i]);
        }
        return Max;
    }
};

394. 字符串解码

394. 字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

class Solution {
public:
    string decodeString(string s) {
    string ans;
        for(int i = 0 ;i<s.size();i++)
        {
            if(s[i]=='[')
            {
                int k, temp1{i-1},temp2{i},n{1};
                while(temp1>=0&&isdigit(s[temp1]))
                    --temp1;
                    ++temp1;
                k = stoi(s.substr(temp1,i-temp1));
                while(n!=0){
                    ++i;
                    if(s[i]=='[')
                        ++n;
                    if(s[i]==']')
                        --n;
                }
                string  str = decodeString(s.substr(temp2+1,i-temp2-1));
                for(int i = 0 ;i<k;i++)
                {
                    ans+=str;
                }
            }
                if(isalpha(s[i]))
                    ans+=s[i];
            
        }
        return ans ==""?s:ans;
    }
};

面试题 01.01. 判定字符是否唯一

面试题 01.01. 判定字符是否唯一
实现一个算法,确定一个字符串 s 的所有字符是否全都不同。

class Solution {
public:
    bool isUnique(string astr) {
        map<char,bool> m;
        for(auto x : astr)
        {
            if(m[x]==0)
                m[x]=true;
            else
                return false;
        }
        return true;
    }
};

面试题 01.02. 判定是否互为字符重排

面试题 01.02. 判定是否互为字符重排
给定两个由小写字母组成的字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

class Solution {
public:
    bool CheckPermutation(string s1, string s2) {
        map<char,int> m;
        for(auto x:s1)
        {
            m[x]++;
        }
        for(auto x:s2)
        {
            m[x]--;
        }
        for(auto x=m.begin();x!=m.end();x++)
        {
            if(x->second!=0)
                return false; 
        }
        return true;
    }
};

309. 最佳买卖股票时机含冷冻期

309. 最佳买卖股票时机含冷冻期
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(!prices.size()) return 0;
        int n = prices.size();
        vector<vector<int>> dp(n,vector<int>(4));
        dp[0][0] = 0,dp[0][1] = 0,dp[0][2] = -prices[0],dp[0][3] = -prices[0];
        for(int i = 1; i < prices.size(); ++i){
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
            dp[i][1] = max(dp[i - 1][2], dp[i - 1][3]) + prices[i];
            dp[i][2] = dp[i - 1][0] - prices[i];
            dp[i][3] = max(dp[i - 1][2], dp[i - 1][3]);
        }
        return max(dp[n - 1][0], dp[n - 1][1]);
    }
};

剑指 Offer 03. 数组中重复的数字

剑指 Offer 03. 数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
    map<int,bool>m;
        for(auto x :nums)
        {
            if(m[x]==true)
                return x;
            m[x]=true;
        }
        return -1;
    }
};

198. 打家劫舍

198. 打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

class Solution {
public:
    int rob(vector<int>& nums) {
    int sum1 = 0;
    int sum2 = 0;
        for(int i =0;i<nums.size();i++)
        {
            if(i%2==0)
            {
                sum2+=nums[i];
                sum2=max(sum1,sum2);
            }
            else
            {
                sum1+=nums[i];
                sum1=max(sum1,sum2);
            }
        }    
        return max(sum1,sum2);
    }
};

337. 打家劫舍 III

337. 打家劫舍 III
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
     unordered_map<TreeNode* ,int>umap;
    int rob(TreeNode* root) {
       if(root==NULL)
           return 0;
        if(root->left==NULL&&root->right==NULL)
            return root->val;
        if(umap[root])
            return umap[root];
        int val1 = root->val;
        if(root->left)
            val1+=rob(root->left->left)+rob(root->left->right);
        if(root->right)
            val1+=rob(root->right->left)+rob(root->right->right);
        int val2 = rob(root->left)+rob(root->right);
        umap[root]=max(val1,val2);
        return max(val1,val2);
    }
};

剑指 Offer 09. 用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

class CQueue {
private:
    stack<int> instack,outstack;

    void in2out(){
        while(!instack.empty())
        {
            outstack.push(instack.top());
            instack.pop();
        }
    }
public:
    CQueue() {
    
    }
    
    void appendTail(int value) {
        instack.push(value);
    }
    
    int deleteHead() {
        if(outstack.empty())
        {
            if(instack.empty())
            return -1;
            in2out();
        }
        
         int value = outstack.top();
    outstack.pop();
    return value;
    }
   
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

剑指 Offer 30. 包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

class MinStack {
public:
    /** initialize your data structure here. */
    stack<int> stack,min_stack;
    MinStack() {
      min_stack.push(INT_MAX);
    }
    
    void push(int x) {
        stack.push(x);
        min_stack.push(::min(min_stack.top(),x));
    }
    
    void pop() {
    stack.pop();
    min_stack.pop();
    }
    
    int top() {
        return stack.top();
    }
    
    int min() {
        return min_stack.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->min();
 */

121. 买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minPrice = INT_MAX;
        int maxProfit = 0;
        
        for (int i = 0; i < prices.size(); i++) {
            if (prices[i] < minPrice) {
                minPrice = prices[i];
            } else if (prices[i] - minPrice > maxProfit) {
                maxProfit = prices[i] - minPrice;
            }
        }
        
        return maxProfit;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值